<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  

   <!-- 百度联盟 -->
   <meta name="baidu_union_verify" content="46e227ad81d5513c6cd8288c18c6ebad">

   <!-- google analytics -->
   <meta name="google-site-verification" content="SzCGQVmA8Mtk40elee-bCGpq2YSCAmEulSNEZHYCkFc" />

   <!--百度站长之家验证-->
   <meta name="baidu-site-verification" content="4woRik4rfk" />

   <meta name="description" content="坑要一个个填，路要一步步走！—— from zhisheng的博客">
   <meta name="keywords" content="Java,架构,后端,服务端,RocketMQ,分布式消息队列,分布式存储,技术博客,HBase,ElasticSearch,Spring,Spring Boot,Spring Boot 2.0,Spring Cloud,Spring MVC,Java EE,前端,HTML,MyBatis,Android,Docker,Mac,Consul,Kafka,Logstash,Kibana,MySQL,Maven,Nginx,Python,RabbitMQ,ActiveMQ,JVM">


  <title>《疯狂 Java 突破程序员基本功的 16 课》读书笔记 | zhisheng的博客</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <meta name="description" content="第 1 课 —— 数组与内存控制数组初始化数组初始化之后，该数组的长度是不可变的（可通过数组的 length 属性访问数组的长度）。Java 中的数组必须经过初始化（为数组对象的元素分配内存空间，并为每个数组元素指定初始值）才可使用。 数组初始化的形式：  静态初始化：初始化时由程序员显示的指定每个数组的初始值，系统决定数组长度。 动态初始化：初始化时程序员只指定数组的长度，系统为数组元素分配初始">
<meta name="keywords" content="Java">
<meta property="og:type" content="article">
<meta property="og:title" content="《疯狂 Java 突破程序员基本功的 16 课》读书笔记">
<meta property="og:url" content="http://www.54tianzhisheng.cn/2017/06/13/Java-16-lession/index.html">
<meta property="og:site_name" content="zhisheng的博客">
<meta property="og:description" content="第 1 课 —— 数组与内存控制数组初始化数组初始化之后，该数组的长度是不可变的（可通过数组的 length 属性访问数组的长度）。Java 中的数组必须经过初始化（为数组对象的元素分配内存空间，并为每个数组元素指定初始值）才可使用。 数组初始化的形式：  静态初始化：初始化时由程序员显示的指定每个数组的初始值，系统决定数组长度。 动态初始化：初始化时程序员只指定数组的长度，系统为数组元素分配初始">
<meta property="og:locale" content="zh-Hans">
<meta property="og:image" content="">
<meta property="og:image" content="http://image.54tianzhisheng.cn/Java%E9%9B%86%E5%90%88%E6%A1%86%E6%9E%B6%E7%B1%BB%E5%9B%BE.jpg">
<meta property="og:image" content="http://www.programcreek.com/wp-content/uploads/2013/03/arraylist-vs-linkedlist-complexity.png">
<meta property="og:image" content="https://ws3.sinaimg.cn/large/006tNc79gy1fp3jkmizmpj30o00didgn.jpg">
<meta property="og:updated_time" content="2018-11-22T14:51:57.000Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="《疯狂 Java 突破程序员基本功的 16 课》读书笔记">
<meta name="twitter:description" content="第 1 课 —— 数组与内存控制数组初始化数组初始化之后，该数组的长度是不可变的（可通过数组的 length 属性访问数组的长度）。Java 中的数组必须经过初始化（为数组对象的元素分配内存空间，并为每个数组元素指定初始值）才可使用。 数组初始化的形式：  静态初始化：初始化时由程序员显示的指定每个数组的初始值，系统决定数组长度。 动态初始化：初始化时程序员只指定数组的长度，系统为数组元素分配初始">
<meta name="twitter:image" content="">
  
    <link rel="alternative" href="/atom.xml" title="zhisheng的博客" type="application/atom+xml">
  
  
    <link rel="icon" href="/img/favicon.ico">
  
  
      <link rel="stylesheet" href="//cdn.bootcss.com/animate.css/3.5.0/animate.min.css">
  
  <link rel="stylesheet" href="/css/style.css">
  <link rel="stylesheet" href="/font-awesome/css/font-awesome.min.css">
  <link rel="apple-touch-icon" href="/apple-touch-icon.png">
  
  
      <link rel="stylesheet" href="/fancybox/jquery.fancybox.css">
  
  <!-- 加载特效 -->
  <script src="/js/pace.js"></script>
  <link href="/css/pace/pace-theme-flash.css" rel="stylesheet" />
  <script>
      var yiliaConfig = {
          rootUrl: '/',
          fancybox: true,
          animate: true,
          isHome: false,
          isPost: true,
          isArchive: false,
          isTag: false,
          isCategory: false,
          open_in_new: true
      }
  </script>
</head>
<body>
  <div id="container">
    <div class="left-col">
    <div class="overlay"></div>
<div class="intrude-less">
    <header id="header" class="inner">
        <a href="/" class="profilepic">
            
            <img lazy-src="/img/avatar.png" class="js-avatar">
            
        </a>

        <hgroup>
          <h1 class="header-author"><a href="/">zhisheng</a></h1>
        </hgroup>

        
        <p class="header-subtitle">坑要一个个填，路要一步步走！</p>
        
        
        
            <div id="switch-btn" class="switch-btn">
                <div class="icon">
                    <div class="icon-ctn">
                        <div class="icon-wrap icon-house" data-idx="0">
                            <div class="birdhouse"></div>
                            <div class="birdhouse_holes"></div>
                        </div>
                        <div class="icon-wrap icon-ribbon hide" data-idx="1">
                            <div class="ribbon"></div>
                        </div>
                        
                        <div class="icon-wrap icon-link hide" data-idx="2">
                            <div class="loopback_l"></div>
                            <div class="loopback_r"></div>
                        </div>
                        
                        
                        <div class="icon-wrap icon-me hide" data-idx="3">
                            <div class="user"></div>
                            <div class="shoulder"></div>
                        </div>
                        
                    </div>
                    
                </div>
                <div class="tips-box hide">
                    <div class="tips-arrow"></div>
                    <ul class="tips-inner">
                        <li>菜单</li>
                        <li>标签</li>
                        
                        <li>友情链接</li>
                        
                        
                        <li>关于我</li>
                        
                    </ul>
                </div>
            </div>
        

        <div id="switch-area" class="switch-area">
            <div class="switch-wrap">
                <section class="switch-part switch-part1">
                    <nav class="header-menu">
                        <ul>
                        
                            <li><a href="/">主页</a></li>
                        
                            <li><a href="/tags/Flink/">Flink</a></li>
                        
                            <li><a href="/tags/ElasticSearch/">ElasticSearch</a></li>
                        
                            <li><a href="/tags/SpringBoot/">Spring Boot</a></li>
                        
                        </ul>
                    </nav>
                    <nav class="header-nav">
                        <ul class="social">
                            
                                <a class="fl wechat" target="_blank" href="wechat:zhisheng_tian" title="wechat">wechat</a>
                            
                                <a class="fl mail" target="_blank" href="mailto://zhisheng2018@gmail.com" title="mail">mail</a>
                            
                                <a class="fl github" target="_blank" href="https://github.com/zhisheng17/" title="github">github</a>
                            
                                <a class="fl zhihu" target="_blank" href="https://www.zhihu.com/people/tian-zhisheng/activities" title="zhihu">zhihu</a>
                            
                        </ul>
                    </nav>
                </section>
                
                
                <section class="switch-part switch-part2">
                    <div class="widget tagcloud" id="js-tagcloud">
                        <a href="/tags/AJAX/" style="font-size: 10px;">AJAX</a> <a href="/tags/ActiveMQ/" style="font-size: 10px;">ActiveMQ</a> <a href="/tags/Android/" style="font-size: 10px;">Android</a> <a href="/tags/Bootstrap/" style="font-size: 13px;">Bootstrap</a> <a href="/tags/Consul/" style="font-size: 10px;">Consul</a> <a href="/tags/Docker/" style="font-size: 11px;">Docker</a> <a href="/tags/ElasticSearch/" style="font-size: 17px;">ElasticSearch</a> <a href="/tags/Filter过滤器/" style="font-size: 10px;">Filter过滤器</a> <a href="/tags/Flink/" style="font-size: 18px;">Flink</a> <a href="/tags/GO/" style="font-size: 10px;">GO</a> <a href="/tags/Github-Page/" style="font-size: 10px;">Github Page</a> <a href="/tags/Guava/" style="font-size: 10px;">Guava</a> <a href="/tags/HBase/" style="font-size: 10px;">HBase</a> <a href="/tags/Hibernate-JPA/" style="font-size: 11px;">Hibernate JPA</a> <a href="/tags/IO/" style="font-size: 11px;">IO</a> <a href="/tags/JMM/" style="font-size: 10px;">JMM</a> <a href="/tags/JSON/" style="font-size: 10px;">JSON</a> <a href="/tags/JVM/" style="font-size: 11px;">JVM</a> <a href="/tags/Java/" style="font-size: 20px;">Java</a> <a href="/tags/Kafka/" style="font-size: 12px;">Kafka</a> <a href="/tags/Kibana/" style="font-size: 10px;">Kibana</a> <a href="/tags/LogStash/" style="font-size: 10px;">LogStash</a> <a href="/tags/Mac/" style="font-size: 10px;">Mac</a> <a href="/tags/Maven/" style="font-size: 11px;">Maven</a> <a href="/tags/MySQL/" style="font-size: 12px;">MySQL</a> <a href="/tags/Mybatis/" style="font-size: 14px;">Mybatis</a> <a href="/tags/NIO/" style="font-size: 10px;">NIO</a> <a href="/tags/Netty/" style="font-size: 10px;">Netty</a> <a href="/tags/Nginx/" style="font-size: 11px;">Nginx</a> <a href="/tags/Oracle/" style="font-size: 10px;">Oracle</a> <a href="/tags/Pyspider/" style="font-size: 10px;">Pyspider</a> <a href="/tags/Python/" style="font-size: 12px;">Python</a> <a href="/tags/RabbitMQ/" style="font-size: 11px;">RabbitMQ</a> <a href="/tags/Redis/" style="font-size: 11px;">Redis</a> <a href="/tags/RocketMQ/" style="font-size: 13px;">RocketMQ</a> <a href="/tags/Servlet/" style="font-size: 10px;">Servlet</a> <a href="/tags/Spring/" style="font-size: 12px;">Spring</a> <a href="/tags/Spring-MVC/" style="font-size: 15px;">Spring MVC</a> <a href="/tags/SpringBoot/" style="font-size: 19px;">SpringBoot</a> <a href="/tags/SpringCloud/" style="font-size: 10px;">SpringCloud</a> <a href="/tags/SpringMVC/" style="font-size: 13px;">SpringMVC</a> <a href="/tags/String/" style="font-size: 10px;">String</a> <a href="/tags/Velocity/" style="font-size: 10px;">Velocity</a> <a href="/tags/Zookeeper/" style="font-size: 10px;">Zookeeper</a> <a href="/tags/finally/" style="font-size: 10px;">finally</a> <a href="/tags/foreach/" style="font-size: 10px;">foreach</a> <a href="/tags/hexo/" style="font-size: 12px;">hexo</a> <a href="/tags/lombok/" style="font-size: 10px;">lombok</a> <a href="/tags/lua/" style="font-size: 10px;">lua</a> <a href="/tags/yilia/" style="font-size: 11px;">yilia</a> <a href="/tags/书籍/" style="font-size: 10px;">书籍</a> <a href="/tags/分布式锁/" style="font-size: 10px;">分布式锁</a> <a href="/tags/前端/" style="font-size: 12px;">前端</a> <a href="/tags/励志/" style="font-size: 10px;">励志</a> <a href="/tags/博客合集/" style="font-size: 10px;">博客合集</a> <a href="/tags/博客网站/" style="font-size: 10px;">博客网站</a> <a href="/tags/多线程/" style="font-size: 11px;">多线程</a> <a href="/tags/大数据/" style="font-size: 18px;">大数据</a> <a href="/tags/字符串/" style="font-size: 11px;">字符串</a> <a href="/tags/实习圈/" style="font-size: 10px;">实习圈</a> <a href="/tags/循环队列/" style="font-size: 10px;">循环队列</a> <a href="/tags/微服务/" style="font-size: 11px;">微服务</a> <a href="/tags/性能调优工具/" style="font-size: 10px;">性能调优工具</a> <a href="/tags/投资理财/" style="font-size: 10px;">投资理财</a> <a href="/tags/数据库/" style="font-size: 12px;">数据库</a> <a href="/tags/数据结构/" style="font-size: 13px;">数据结构</a> <a href="/tags/文件/" style="font-size: 10px;">文件</a> <a href="/tags/旋转词/" style="font-size: 10px;">旋转词</a> <a href="/tags/流式计算/" style="font-size: 18px;">流式计算</a> <a href="/tags/流控/" style="font-size: 10px;">流控</a> <a href="/tags/爬虫/" style="font-size: 12px;">爬虫</a> <a href="/tags/算法/" style="font-size: 12px;">算法</a> <a href="/tags/类加载机制/" style="font-size: 10px;">类加载机制</a> <a href="/tags/线程池/" style="font-size: 10px;">线程池</a> <a href="/tags/编码/" style="font-size: 10px;">编码</a> <a href="/tags/表达式/" style="font-size: 10px;">表达式</a> <a href="/tags/邮件发送/" style="font-size: 10px;">邮件发送</a> <a href="/tags/随笔/" style="font-size: 16px;">随笔</a> <a href="/tags/面经/" style="font-size: 16px;">面经</a>
                    </div>
                </section>
                
                
                
                <section class="switch-part switch-part3">
                    <div id="js-friends">
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://blog.csdn.net/tzs_1041218129">CSDN博客</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="https://juejin.im/user/57510b82128fe10056ca70fc">掘金</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://www.iocoder.cn/?vip">芋道源码</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://fengzhaofeng.net/">冯兆峯</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://www.codedata.cn/">CodeData</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="https://investguider.com/">美股指南</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://www.songyawei.cn/">Linux运维工程师</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://www.carlzone.cn/">carl.zhao</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://dongkelun.com/">伦少的博客</a>
                    
                      <a target="_blank" class="main-nav-link switch-friends-link" href="http://www.jiangxinlingdu.com/">匠心零度</a>
                    
                    </div>
                </section>
                

                
                
                <section class="switch-part switch-part4">
                
                    <div id="js-aboutme">17.08 ~ 18.05 永辉云创基础架构组实习     2018.06 大学毕业   2018.06 ～ 现在  另一家公司各种折腾!</div>
                </section>
                
            </div>
        </div>
        <div>
            <img src="/img/wx.jpg"  alt="zhisheng" />
        </div>
    </header>
</div>
    </div>
    <div class="mid-col">
      <nav id="mobile-nav">
      <div class="overlay">
          <div class="slider-trigger"></div>
          <h1 class="header-author js-mobile-header hide"><a href="/" title="Me">zhisheng</a></h1>
      </div>
    <div class="intrude-less">
        <header id="header" class="inner">
            <a href="/" class="profilepic">
                
                    <img lazy-src="/img/avatar.png" class="js-avatar">
                
            </a>
            <hgroup>
              <h1 class="header-author"><a href="/" title="Me">zhisheng</a></h1>
            </hgroup>
            
            <p class="header-subtitle">坑要一个个填，路要一步步走！</p>
            
            <nav class="header-menu">
                <ul>
                
                    <li><a href="/">主页</a></li>
                
                    <li><a href="/tags/Flink/">Flink</a></li>
                
                    <li><a href="/tags/ElasticSearch/">ElasticSearch</a></li>
                
                    <li><a href="/tags/SpringBoot/">Spring Boot</a></li>
                
                <div class="clearfix"></div>
                </ul>
            </nav>
            <nav class="header-nav">
                <div class="social">
                    
                        <a class="wechat" target="_blank" href="wechat:zhisheng_tian" title="wechat">wechat</a>
                    
                        <a class="mail" target="_blank" href="mailto://zhisheng2018@gmail.com" title="mail">mail</a>
                    
                        <a class="github" target="_blank" href="https://github.com/zhisheng17/" title="github">github</a>
                    
                        <a class="zhihu" target="_blank" href="https://www.zhihu.com/people/tian-zhisheng/activities" title="zhihu">zhihu</a>
                    
                </div>
            </nav>
        </header>                
    </div>
</nav>
      <div class="body-wrap"><article id="post-Java-16-lession" class="article article-type-post" itemscope itemprop="blogPost">
  
    <div class="article-meta">
      <a href="/2017/06/13/Java-16-lession/" class="article-date">
      <time datetime="2017-06-12T16:00:00.000Z" itemprop="datePublished">2017-06-13</time>
</a>
    </div>
  
  <div class="article-inner">
    
      <input type="hidden" class="isFancy" />
    
    
      <header class="article-header">
        
  
    <h1 class="article-title" itemprop="name">
      《疯狂 Java 突破程序员基本功的 16 课》读书笔记
    </h1>
  

      </header>
      
      <div class="article-info article-info-post">
        

        
    <div class="article-tag tagcloud">
        <ul class="article-tag-list"><li class="article-tag-list-item"><a class="article-tag-list-link" href="/tags/Java/">Java</a></li></ul>
    </div>

        <div class="clearfix"></div>
      </div>
      
    
    <div class="article-entry" itemprop="articleBody">
      
          
        <h2 id="第-1-课-——-数组与内存控制"><a href="#第-1-课-——-数组与内存控制" class="headerlink" title="第 1 课 —— 数组与内存控制"></a>第 1 课 —— 数组与内存控制</h2><h3 id="数组初始化"><a href="#数组初始化" class="headerlink" title="数组初始化"></a>数组初始化</h3><p>数组初始化之后，该数组的长度是不可变的（可通过数组的 length 属性访问数组的长度）。Java 中的数组必须经过初始化（为数组对象的元素分配内存空间，并为每个数组元素指定初始值）才可使用。</p>
<p>数组初始化的形式：</p>
<ul>
<li>静态初始化：初始化时由程序员显示的指定每个数组的初始值，系统决定数组长度。</li>
<li>动态初始化：初始化时程序员只指定数组的长度，系统为数组元素分配初始值。</li>
</ul>
<a id="more"></a>
<h3 id="使用数组"><a href="#使用数组" class="headerlink" title="使用数组"></a>使用数组</h3><p>数组元素就是变量：例如 int[] 数组元素相当于 int 类型的变量</p>
<p>当通过索引来使用数组元素时（访问数组元素的值、为数组元素赋值），将该数组元素当成普通变量使用即可。</p>
<h2 id="第-2-课-——-对象与内存的控制"><a href="#第-2-课-——-对象与内存的控制" class="headerlink" title="第 2 课 —— 对象与内存的控制"></a>第 2 课 —— 对象与内存的控制</h2><p>Java 内存管理分为：内存分配和内存回收。</p>
<blockquote>
<ul>
<li>内存分配：创建 Java 对象时 JVM 为该对象在堆内存中所分配的内存空间。</li>
<li>内存回收：当 Java 对象失去引用，变成垃圾，JVM 的垃圾回收机制自动清理该对象，并回收内存</li>
</ul>
</blockquote>
<h3 id="实例变量-和-类变量"><a href="#实例变量-和-类变量" class="headerlink" title="实例变量 和 类变量"></a>实例变量 和 类变量</h3><h4 id="局部变量"><a href="#局部变量" class="headerlink" title="局部变量"></a>局部变量</h4><p>特点：作用时间短，存储在方法的栈内存中</p>
<p>种类：</p>
<ul>
<li>形参：方法签名中定义的局部变量，由方法调用者负责为其赋值，随方法结束而消亡</li>
<li>方法内的局部变量：方法内定义的局部变量，必须在方法内对其进行显示初始化，从初始化后开始生效，随方法结束而消亡</li>
<li>代码块内的局部变量：在代码块中定义的局部变量，必须在代码块中进行显示初始化，从初始化后开始生效，随代码块结束而消亡</li>
</ul>
<h4 id="成员变量"><a href="#成员变量" class="headerlink" title="成员变量"></a>成员变量</h4><p>类体内定义的变量，如果该成员变量没有使用 static 修饰，那该成员变量又被称为非静态变量或实例变量，如果使用 static 修饰，则该成员变量又可被称为静态变量或类变量。</p>
<h4 id="实例变量和类变量的属性"><a href="#实例变量和类变量的属性" class="headerlink" title="实例变量和类变量的属性"></a>实例变量和类变量的属性</h4><p>使用 static 修饰的成员变量是类变量，属于该类本身，没有使用 static 修饰的成员变量是实例变量，属于该类的实例，在同一个类中，每一个类只对应一个 Class 对象，但每个类可以创建多个对象。</p>
<p>由于同一个 JVM 内的每个类只对应一个 CLass 对象，因此同一个 JVM 内的一个类的类变量只需要一块内存空间；但对于实例变量而言，该类每创建一次实例，就需要为该实例变量分配一块内存空间。也就是说，程序中创建了几个实例，实例变量就需要几块内存空间。</p>
<p>这里我想到一道面试题目：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">A</span></span>&#123;</span><br><span class="line">  &#123;</span><br><span class="line">    System.out.println(<span class="string">"我是代码块"</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">static</span>&#123;</span><br><span class="line">    System.out.println(<span class="string">"我是静态代码块"</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        A a = <span class="keyword">new</span> A();</span><br><span class="line">        A a1 = <span class="keyword">new</span> A();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>结果：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">我是静态代码块</span><br><span class="line">我是代码块</span><br><span class="line">我是代码块</span><br></pre></td></tr></table></figure>
<p>静态代码块只执行一次，而代码块每创建一个实例，就会打印一次。</p>
<h4 id="实例变量的初始化时机"><a href="#实例变量的初始化时机" class="headerlink" title="实例变量的初始化时机"></a>实例变量的初始化时机</h4><p>程序可在3个地方对实例变量执行初始化：</p>
<ul>
<li>定义实例变量时指定初始值</li>
<li>非静态初始化块中对实例变量指定初始值</li>
<li>构造器中对实例变量指定初始值</li>
</ul>
<p>上面第一种和第二种方式比第三种方式更早执行，但第一、二种方式的执行顺序与他们在源程序中的排列顺序相同。</p>
<p>同样在上面那个代码上加上一个变量 weight 的成员变量，我们来验证下上面的初始化顺序：</p>
<p>1、<code>定义实例变量指定初始值</code> 在 <code>非静态初始化块对实例变量指定初始值</code> 之后:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">A</span></span>&#123;</span><br><span class="line">    &#123;</span><br><span class="line">        weight = <span class="number">2.1</span>;</span><br><span class="line">        System.out.println(<span class="string">"我是代码块"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">double</span> weight = <span class="number">2.0</span>;</span><br><span class="line">    <span class="keyword">static</span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"我是静态代码块"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        A a = <span class="keyword">new</span> A();</span><br><span class="line">        A a1 = <span class="keyword">new</span> A();</span><br><span class="line">        System.out.println(a.weight);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>结果是：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">我是静态代码块</span><br><span class="line">我是代码块</span><br><span class="line">我是代码块</span><br><span class="line">2.0</span><br></pre></td></tr></table></figure>
<p>2、<code>定义实例变量指定初始值</code> 在 <code>非静态初始化块对实例变量指定初始值</code> 之前:</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">A</span></span>&#123;</span><br><span class="line">	<span class="keyword">double</span> weight = <span class="number">2.0</span>;</span><br><span class="line">    &#123;</span><br><span class="line">        weight = <span class="number">2.1</span>;</span><br><span class="line">        System.out.println(<span class="string">"我是代码块"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">static</span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"我是静态代码块"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        A a = <span class="keyword">new</span> A();</span><br><span class="line">        A a1 = <span class="keyword">new</span> A();</span><br><span class="line">        System.out.println(a.weight);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>结果为：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">我是静态代码块</span><br><span class="line">我是代码块</span><br><span class="line">我是代码块</span><br><span class="line">2.1</span><br></pre></td></tr></table></figure>
<p>大家有没有觉得很奇怪？</p>
<p>我来好好说清楚下：</p>
<blockquote>
<p>定义实例变量时指定的初始值、初始代码块中为实例变量指定初始值的语句的地位是平等的，当经过编译器处理后，他们都将会被提取到构造器中。也就是说，这条语句 <code>double weight = 2.0;</code> 实际上会被分成如下 2 次执行：</p>
<ul>
<li><code>double weight;</code> : 创建 Java 对象时系统根据该语句为该对象分配内存。</li>
<li><code>weight = 2.1;</code> : 这条语句将会被提取到 Java 类的构造器中执行。</li>
</ul>
</blockquote>
<p>只说原理，大家肯定不怎么信，那么还有拿出源码来，这样才有信服能力的吗？是不？</p>
<p>这里我直接使用软件将代码的字节码文件反编译过来，看看里面是怎样的组成？</p>
<p>第一个代码的反编译源码如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">A</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">  <span class="keyword">double</span> weight;</span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="title">A</span><span class="params">()</span></span></span><br><span class="line"><span class="function">  </span>&#123;</span><br><span class="line">    <span class="keyword">this</span>.weight = <span class="number">2.1</span>D;</span><br><span class="line">    System.out.println(<span class="string">"我是代码块"</span>);</span><br><span class="line">    <span class="keyword">this</span>.weight = <span class="number">2.0</span>D;</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">static</span></span><br><span class="line">  &#123;</span><br><span class="line">    System.out.println(<span class="string">"我是静态代码块"</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span></span></span><br><span class="line"><span class="function">  </span>&#123;</span><br><span class="line">    A a = <span class="keyword">new</span> A();</span><br><span class="line">    A a1 = <span class="keyword">new</span> A();</span><br><span class="line">    System.out.println(a.weight);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>第二个代码反编译源码如下：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">A</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">  <span class="keyword">double</span> weight;</span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="title">A</span><span class="params">()</span></span></span><br><span class="line"><span class="function">  </span>&#123;</span><br><span class="line">    <span class="keyword">this</span>.weight = <span class="number">2.0</span>D;</span><br><span class="line">    <span class="keyword">this</span>.weight = <span class="number">2.1</span>D;</span><br><span class="line">    System.out.println(<span class="string">"我是代码块"</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">static</span></span><br><span class="line">  &#123;</span><br><span class="line">    System.out.println(<span class="string">"我是静态代码块"</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span></span></span><br><span class="line"><span class="function">  </span>&#123;</span><br><span class="line">    A a = <span class="keyword">new</span> A();</span><br><span class="line">    A a1 = <span class="keyword">new</span> A();</span><br><span class="line">    System.out.println(a.weight);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这下子满意了吧！</p>
<p>通过反编译的源码可以看到该类定义的 weight 实例变量时不再有初始值，为 weight 指定初始值的代码也被提到了构造器中去了，但是我们也可以发现之前规则也是满足的。</p>
<p>他们的赋值语句都被合并到构造器中，在合并过程中，定义的变量语句转换得到的赋值语句，初始代码块中的语句都转换得到的赋值语句，总是位于构造器的所有语句之前，合并后，两种赋值语句的顺序也保持了它们在 Java 源代码中的顺序。</p>
<p>大致过程应该了解了吧？如果还不怎么清楚的，建议还是自己将怎个过程在自己的电脑上操作一遍，毕竟光看不练假把式。</p>
<h4 id="类变量的初始化时机"><a href="#类变量的初始化时机" class="headerlink" title="类变量的初始化时机"></a>类变量的初始化时机</h4><p>JVM 对每一个 Java 类只初始化一次，因此 Java 程序每运行一次，系统只为类变量分配一次内存空间，执行一次初始化。程序可在两个地方对类变量执行初始化：</p>
<ul>
<li>定义类变量时指定初始值</li>
<li>静态初始化代码块中对类变量指定初始值</li>
</ul>
<p>这两种方式的执行顺序与它们在源代码中的排列顺序相同。</p>
<p>还是用上面那个示例，我们在其基础上加个被 static 修饰的变量 height：</p>
<p>1、<code>定义类变量时指定初始值</code> 在 <code>静态初始化代码块中对类变量指定初始值</code> 之后：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">A</span></span>&#123;</span><br><span class="line">    <span class="keyword">double</span> weight = <span class="number">2.0</span>;</span><br><span class="line">    &#123;</span><br><span class="line">        weight = <span class="number">2.1</span>;</span><br><span class="line">        System.out.println(<span class="string">"我是代码块"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">static</span>&#123;</span><br><span class="line">        height = <span class="number">10.1</span>;</span><br><span class="line">        System.out.println(<span class="string">"我是静态代码块"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">double</span> height = <span class="number">10.0</span>;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        A a = <span class="keyword">new</span> A();</span><br><span class="line">        A a1 = <span class="keyword">new</span> A();</span><br><span class="line">        System.out.println(a.weight);</span><br><span class="line">        System.out.println(height);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>运行结果：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">我是静态代码块</span><br><span class="line">我是代码块</span><br><span class="line">我是代码块</span><br><span class="line">2.1</span><br><span class="line">10.0</span><br></pre></td></tr></table></figure>
<p>2、<code>定义类变量时指定初始值</code> 在 <code>静态初始化代码块中对类变量指定初始值</code> 之前：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">A</span></span>&#123;</span><br><span class="line">    <span class="keyword">static</span> <span class="keyword">double</span> height = <span class="number">10.0</span>;</span><br><span class="line">    <span class="keyword">double</span> weight = <span class="number">2.0</span>;</span><br><span class="line">    &#123;</span><br><span class="line">        weight = <span class="number">2.1</span>;</span><br><span class="line">        System.out.println(<span class="string">"我是代码块"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">static</span>&#123;</span><br><span class="line">        height = <span class="number">10.1</span>;</span><br><span class="line">        System.out.println(<span class="string">"我是静态代码块"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        A a = <span class="keyword">new</span> A();</span><br><span class="line">        A a1 = <span class="keyword">new</span> A();</span><br><span class="line">        System.out.println(a.weight);</span><br><span class="line">        System.out.println(height);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>运行结果：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">我是静态代码块</span><br><span class="line">我是代码块</span><br><span class="line">我是代码块</span><br><span class="line">2.1</span><br><span class="line">10.1</span><br></pre></td></tr></table></figure>
<p>其运行结果正如我们预料，但是我们还是看看反编译后的代码吧！</p>
<p>第一种情况下反编译的代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">A</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">  <span class="keyword">double</span> weight;</span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="title">A</span><span class="params">()</span></span></span><br><span class="line"><span class="function">  </span>&#123;</span><br><span class="line">    <span class="keyword">this</span>.weight = <span class="number">2.0</span>D;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">this</span>.weight = <span class="number">2.1</span>D;</span><br><span class="line">    System.out.println(<span class="string">"我是代码块"</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">static</span></span><br><span class="line">  &#123;</span><br><span class="line">    System.out.println(<span class="string">"我是静态代码块"</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">static</span> <span class="keyword">double</span> height = <span class="number">10.0</span>D;</span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span></span></span><br><span class="line"><span class="function">  </span>&#123;</span><br><span class="line">    A a = <span class="keyword">new</span> A();</span><br><span class="line">    A a1 = <span class="keyword">new</span> A();</span><br><span class="line">    System.out.println(a.weight);</span><br><span class="line">    System.out.println(height);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>第二种情况下反编译的代码：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">A</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">  <span class="keyword">static</span> <span class="keyword">double</span> height = <span class="number">10.0</span>D;</span><br><span class="line">  <span class="keyword">double</span> weight;</span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="title">A</span><span class="params">()</span></span></span><br><span class="line"><span class="function">  </span>&#123;</span><br><span class="line">    <span class="keyword">this</span>.weight = <span class="number">2.0</span>D;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">this</span>.weight = <span class="number">2.1</span>D;</span><br><span class="line">    System.out.println(<span class="string">"我是代码块"</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="keyword">static</span></span><br><span class="line">  &#123;</span><br><span class="line">    height = <span class="number">10.1</span>D;</span><br><span class="line">    System.out.println(<span class="string">"我是静态代码块"</span>);</span><br><span class="line">  &#125;</span><br><span class="line">  <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span></span></span><br><span class="line"><span class="function">  </span>&#123;</span><br><span class="line">    A a = <span class="keyword">new</span> A();</span><br><span class="line">    A a1 = <span class="keyword">new</span> A();</span><br><span class="line">    System.out.println(a.weight);</span><br><span class="line">    System.out.println(height);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>通过反编译源码，可以看到第一种情况下(<code>定义类变量时指定初始值</code> 在 <code>静态初始化代码块中对类变量指定初始值</code> 之后):</p>
<p>我们在 <strong>静态初始化代码块中对类变量指定初始值</strong> 已经不存在了，只有一个类变量指定的初始值 <code>static double height = 10.0D;</code> , 而在第二种情况下（<code>定义类变量时指定初始值</code> 在 <code>静态初始化代码块中对类变量指定初始值</code> 之前）和之前的源代码顺序是一样的，没啥区别。</p>
<p>上面的代码中充分的展示了类变量的两种初始化方式 ：每次运行该程序时，系统会为 A 类执行初始化，先为所有类变量分配内存空间，再按照源代码中的排列顺序执行静态初始代码块中所指定的初始值和定义类变量时所指定的初始值。</p>
<h3 id="父类构造器"><a href="#父类构造器" class="headerlink" title="父类构造器"></a>父类构造器</h3><p>当创建任何 Java 对象时，程序总会先依次调用每个父类非静态初始化代码块、父类构造器（总是从 Object 开始）执行初始化，最后才调用本类的非静态初始化代码块、构造器执行初始化。</p>
<h4 id="隐式调用和显示调用"><a href="#隐式调用和显示调用" class="headerlink" title="隐式调用和显示调用"></a>隐式调用和显示调用</h4><p>当调用某个类的构造器来创建 Java 对象时，系统总会先调用父类的非静态初始化代码块进行初始化。这个调用是隐式执行的，而且父类的静态初始化代码块总是会被执行。接着会调用父类的一个或多个构造器执行初始化，这个调用既可以是通过 super 进行显示调用，也可以是隐式调用。</p>
<p>当所有父类的非静态初始代码块、构造器依次调用完成后，系统调用本类的非静态代码块、构造器执行初始化，最后返回本类的实例。至于调用父类的哪个构造器执行初始化，分以下几种情况：</p>
<ul>
<li>子类构造器执行体的第一行代码使用 super 显式调用父类构造器，系统将根据 super 调用里传入的实参列表来确定调用父类的哪个构造器；</li>
<li>子类构造器执行体的第一行代码使用 this 显式调用本类中的重载构造器，系统将根据 this 调用里传入的实参列表来确定奔雷的另一个构造器（执行本类中另一个构造器时即进入第一种情况）；</li>
<li>子类构造器中既没有 super 调用，也没有 this 调用，系统将会在执行子类构造器之前，隐式调用父类无参构造器。</li>
</ul>
<p>注：super 和 this 必须在构造器的第一行，且不能同时存在。</p>
<p>推荐一篇博客：<a href="http://www.cnblogs.com/miniwiki/archive/2011/03/25/1995615.html">Java初始化顺序</a> 文章从无继承和继承两种情况下分析了 Java 初始化的顺序。</p>
<p><strong>Java初始化顺序如图：</strong></p>
<p><img src="" alt=""></p>
<h4 id="访问子类对象的实例变量"><a href="#访问子类对象的实例变量" class="headerlink" title="访问子类对象的实例变量"></a>访问子类对象的实例变量</h4><h4 id="调用被子类重写的方法"><a href="#调用被子类重写的方法" class="headerlink" title="调用被子类重写的方法"></a>调用被子类重写的方法</h4><h3 id="父子实例的内存控制"><a href="#父子实例的内存控制" class="headerlink" title="父子实例的内存控制"></a>父子实例的内存控制</h3><h4 id="继承成员变量和继承方法的区别"><a href="#继承成员变量和继承方法的区别" class="headerlink" title="继承成员变量和继承方法的区别"></a>继承成员变量和继承方法的区别</h4><p>方法的行为总是表现出它们实际类型的行为；实例变量的值总是表现出声明这些变量所用类型的行为。</p>
<h4 id="内存中的子类实例"><a href="#内存中的子类实例" class="headerlink" title="内存中的子类实例"></a>内存中的子类实例</h4><h4 id="父、子类的类变量"><a href="#父、子类的类变量" class="headerlink" title="父、子类的类变量"></a>父、子类的类变量</h4><h3 id="final-修饰符"><a href="#final-修饰符" class="headerlink" title="final 修饰符"></a>final 修饰符</h3><p>final 可以修饰变量、方法、类。</p>
<ul>
<li>修饰变量，变量被赋初始值之后，不能够对他在进行修改</li>
<li>修饰方法，不能够被重写</li>
<li>修饰类，不能够被继承</li>
</ul>
<p>final 修饰的实例变量只能在如下位置指定初始值：</p>
<ul>
<li>定义 final 实例变量时指定初始值</li>
<li>在非静态代码块中为 final 实例变量指定初始值</li>
<li>在构造器中为 final 实例变量指定初始值</li>
</ul>
<p>final 修饰的类变量只能在如下位置指定初始值：</p>
<ul>
<li>定义 final 类变量时指定初始值</li>
<li>在静态代码块中为 final 类变量指定初始值</li>
</ul>
<h2 id="第-3-课-——-常见-Java-集合的实现细节"><a href="#第-3-课-——-常见-Java-集合的实现细节" class="headerlink" title="第 3 课 —— 常见 Java 集合的实现细节"></a>第 3 课 —— 常见 Java 集合的实现细节</h2><p>Java 集合框架类图：</p>
<p><img src="http://image.54tianzhisheng.cn/Java%E9%9B%86%E5%90%88%E6%A1%86%E6%9E%B6%E7%B1%BB%E5%9B%BE.jpg" alt=""></p>
<h3 id="Set-和-Map"><a href="#Set-和-Map" class="headerlink" title="Set 和 Map"></a>Set 和 Map</h3><p>Set 代表一种集合元素无序、集合元素不可重复的集合，Map 则代表一种由多个 key-value 对组合的集合，Map 集合类似于传统的关联数组。</p>
<h4 id="Set-和-Map-的关系"><a href="#Set-和-Map-的关系" class="headerlink" title="Set 和 Map 的关系"></a>Set 和 Map 的关系</h4><p>1、Map 集合中的 key 不能重复且没有顺序。将这些 key 组合起来就是一个 Set 集合。所以有一个 <code>Set&lt;k&gt; keySet()</code> 方法来返回所有 key 组成的 Set 集合。</p>
<p>2、Set 也可以转换成 Map。（在 Set 中将 每一对 key 和 value 存放在一起）</p>
<h4 id="HashMap-和-HashSet"><a href="#HashMap-和-HashSet" class="headerlink" title="HashMap 和 HashSet"></a>HashMap 和 HashSet</h4><p>HashSet：系统采用 Hash 算法决定集合元素的存储位置。（基于 HashMap 实现的）</p>
<p>HashMap：系统将 value 当成 key 的附属，系统根据 Hash 算法决定 key 的存储位置。</p>
<p>HashSet 的绝大部分方法都是通过调用 HashMap 的方法实现的，因此 HashSet 和 HashMap 两个集合在实现本质上是相同的。</p>
<h4 id="TreeMap-和-TreeSet"><a href="#TreeMap-和-TreeSet" class="headerlink" title="TreeMap 和 TreeSet"></a>TreeMap 和 TreeSet</h4><p>TreeSet 底层使用 TreeMap 来包含 Set 集合中的所有元素。</p>
<p>TreeMap 采用的是一种“红黑树”的排序二叉树来保存 Map 中每个 Entry —— 每个 Entry 都被当成 “红黑树” 的一个节点对待。</p>
<h3 id="Map-和-List"><a href="#Map-和-List" class="headerlink" title="Map 和 List"></a>Map 和 List</h3><h4 id="Map-的-values-方法"><a href="#Map-的-values-方法" class="headerlink" title="Map 的 values() 方法"></a>Map 的 values() 方法</h4><p>不管是 HashMap 还是 TreeMap ，它们的 values() 方法都可以返回其所有 value 组成的 Collection 集合，其实是一个不存储元素的 Collection 集合，当程序遍历 Collection 集合时，实际上就是遍历 Map 对象的 value。</p>
<p>HashMap 和 TreeMap 的 values() 方法并未把 Map 中的 values 重新组合成一个包含元素的集合对象，这样就可以降低系统内存开销。</p>
<h4 id="Map-和-List-的关系"><a href="#Map-和-List-的关系" class="headerlink" title="Map 和 List 的关系"></a>Map 和 List 的关系</h4><p>底层实现很相似；用法上很相似。</p>
<ul>
<li>Map 接口提供 get(K key) 方法允许 Map 对象根据 key 来取得 value；</li>
<li>List 接口提供了 get(int index) 方法允许 List 对象根据元素索引来取得 value；</li>
</ul>
<h3 id="ArrayList-和-LinkedList"><a href="#ArrayList-和-LinkedList" class="headerlink" title="ArrayList 和 LinkedList"></a>ArrayList 和 LinkedList</h3><p>List 集合的实现类，主要有 ArrayList 、Vector 和 LinkedList。</p>
<ul>
<li><strong>ArrayList </strong>是一个可改变大小的数组.当更多的元素加入到 ArrayList 中时, 其大小将会动态地增长.  内部的元素可以直接通过 get 与 set 方法进行访问, 因为 ArrayList 本质上就是一个数组.</li>
<li><strong>LinkedList </strong>是一个双链表, 在添加和删除元素时具有比 ArrayList 更好的性能. 但在 get 与 set 方面弱于ArrayList. 当然, 这些对比都是指数据量很大或者操作很频繁的情况下的对比, 如果数据和运算量很小,那么对比将失去意义.</li>
<li><strong>Vector </strong>和 ArrayList 类似, 但属于强同步类。如果你的程序本身是线程安全的(thread-safe,没有在多个线程之间共享同一个集合/对象),那么使用 ArrayList 是更好的选择。</li>
</ul>
<p>Vector 和 ArrayList 在更多元素添加进来时会请求更大的空间。Vector 每次请求其大小的双倍空间，而 ArrayList每次对 size 增长 50%.</p>
<p>而 LinkedList 还实现了 Queue 接口, 该接口比 List 提供了更多的方法,包括 offer(), peek(), poll()等.</p>
<p>注意: 默认情况下 ArrayList 的初始容量非常小, 所以如果可以预估数据量的话, 分配一个较大的初始值属于最佳实践, 这样可以减少调整大小的开销。</p>
<p>ArrayList与LinkedList性能对比</p>
<p>时间复杂度对比如下:</p>
<p><img src="http://www.programcreek.com/wp-content/uploads/2013/03/arraylist-vs-linkedlist-complexity.png" alt=""></p>
<p>LinkedList 更适用于:</p>
<ul>
<li>没有大规模的随机读取</li>
<li>大量的增加/删除操作</li>
</ul>
<h3 id="Iterator-迭代器"><a href="#Iterator-迭代器" class="headerlink" title="Iterator 迭代器"></a>Iterator 迭代器</h3><p>是一个迭代器接口，专门用于迭代各种 Collection 集合，包括 Set  集合和 List 集合。</p>
<h2 id="第-4-课-——-Java-的内存回收"><a href="#第-4-课-——-Java-的内存回收" class="headerlink" title="第 4 课 —— Java 的内存回收"></a>第 4 课 —— Java 的内存回收</h2><h3 id="Java-引用的种类"><a href="#Java-引用的种类" class="headerlink" title="Java 引用的种类"></a>Java 引用的种类</h3><h4 id="对象在内存中的状态"><a href="#对象在内存中的状态" class="headerlink" title="对象在内存中的状态"></a>对象在内存中的状态</h4><p>JVM 垃圾回收机制，是否回收一个对象的标准在于：是否还有引用变量引用该对象？只要有引用变量引用该对象，垃圾回收机制就不会回收它。</p>
<p>Java 语言对对象的引用有：</p>
<ul>
<li>强引用</li>
<li>软引用</li>
<li>弱引用</li>
<li>虚引用</li>
</ul>
<h4 id="强引用"><a href="#强引用" class="headerlink" title="强引用"></a>强引用</h4><p>程序创建一个对象，并把这个对象赋给一个引用变量，这个引用变量就是强引用。当一个对象被一个或者一个以上的强引用变量所引用时，它处于可达状态，它是不会被系统的垃圾回收机制回收。</p>
<h4 id="软引用"><a href="#软引用" class="headerlink" title="软引用"></a>软引用</h4><p>软引用需要通过 SoftReference 类来实现，当一个对象只具有软引用时，它有可能会被垃圾回收机制回收。对于只有软引用的对象而言，当系统内存空间足够时，它不会被系统回收，程序也可使用该对象；当系统内存空间不足时，系统将会回收它。</p>
<h4 id="弱引用"><a href="#弱引用" class="headerlink" title="弱引用"></a>弱引用</h4><p>弱引用和软引用有点相似，区别在于弱引用所引用对象的生存期更短。</p>
<h4 id="虚引用"><a href="#虚引用" class="headerlink" title="虚引用"></a>虚引用</h4><p>虚引用主要用于跟踪对象被垃圾回收的状态，虚引用不能单独使用，虚引用必须和引用队列联合使用。</p>
<h3 id="Java-的内存泄漏"><a href="#Java-的内存泄漏" class="headerlink" title="Java 的内存泄漏"></a>Java 的内存泄漏</h3><p>ArrayList.java 中的 remove 方法</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> E <span class="title">remove</span><span class="params">(<span class="keyword">int</span> index)</span> </span>&#123;</span><br><span class="line">        rangeCheck(index);</span><br><span class="line">        modCount++;</span><br><span class="line">        E oldValue = elementData(index);</span><br><span class="line">        <span class="keyword">int</span> numMoved = size - index - <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">if</span> (numMoved &gt; <span class="number">0</span>)</span><br><span class="line">            System.arraycopy(elementData, index+<span class="number">1</span>, elementData, index,</span><br><span class="line">                             numMoved);</span><br><span class="line">        elementData[--size] = <span class="keyword">null</span>; <span class="comment">// clear to let GC do its work</span></span><br><span class="line">        <span class="keyword">return</span> oldValue;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>
<p>其中 <code>elementData[--size] = null; // clear to let GC do its work</code> 语句是清除数组元素的引用，避免内存的泄漏，如果没有这句的话，那么就是只有两个作用：</p>
<ul>
<li>修饰 Stack 的属性，也就是将值减 1；</li>
<li>返回索引为 size -1 的值。</li>
</ul>
<h3 id="垃圾回收机制"><a href="#垃圾回收机制" class="headerlink" title="垃圾回收机制"></a>垃圾回收机制</h3><ul>
<li>跟踪并监控每个 Java 对象，当某个对象处于不可达状态时，回收该对象所占用的内存。</li>
<li>清理内存分配，回收过程中产生的内存碎片。</li>
</ul>
<h4 id="垃圾回收的基本算法"><a href="#垃圾回收的基本算法" class="headerlink" title="垃圾回收的基本算法"></a>垃圾回收的基本算法</h4><p>对于一个垃圾回收器的设计算法来说，大概有如下几个设计：</p>
<ul>
<li><p>串行回收 和 并行回收</p>
<blockquote>
<p>串行回收：不管系统有多少个 CPU，始终使用一个 CPU 来执行垃圾回收操作</p>
<p>并行回收：把整个回收工作拆分成多部分，每个部分由一个 CPU 负责，从而让多个 CPU 并行回收</p>
</blockquote>
</li>
<li><p>并发执行 和 应用程序停止</p>
</li>
<li><p>压缩 和 不压缩 和 复制</p>
<blockquote>
<ul>
<li>复制：将堆内分成两个相同的空间，从根开始访问每一个关联的可达对象，将空间A的可达对象全部复制到空间B，然后一次性回收整个空间A。</li>
<li>标记清除：也就是 不压缩 的回收方式。垃圾回收器先从根开始访问所有可达对象，将它们标记为可达状态，然后再遍历一次整个内存区域，把所有没有标记为可达的对象进行回收处理。</li>
<li>标记压缩：这是压缩方式，这种方式充分利用上述两种算法的优点，垃圾回收器先从根开始访问所有可达对象，将他们标记为可达状态，接下来垃圾回收器会将这些活动对象搬迁在一起，这个过程叫做内存压缩，然后垃圾回收机制再次回收那些不可达对象所占用的内存空间，这样就避免了回收产生的内存碎片。</li>
</ul>
</blockquote>
</li>
</ul>
<h4 id="堆内存的分代回收"><a href="#堆内存的分代回收" class="headerlink" title="堆内存的分代回收"></a>堆内存的分代回收</h4><p>1、Young 代</p>
<p>2、Old 代</p>
<p>3、Permanent 代</p>
<h3 id="内存管理小技巧"><a href="#内存管理小技巧" class="headerlink" title="内存管理小技巧"></a>内存管理小技巧</h3><ul>
<li>尽量使用直接量</li>
<li>使用 StringBuilder 和 StringBuffer 进行字符串拼接</li>
<li>尽早释放无用对象的引用</li>
<li>尽量少用静态变量</li>
<li>避免在经常调用的方法、循环中创建 Java 对象</li>
<li>缓存经常使用的对象</li>
<li>尽量不要使用 finalize 方法</li>
<li>考虑使用 SoftReference</li>
</ul>
<h2 id="第-5-课-——-表达式中的陷阱"><a href="#第-5-课-——-表达式中的陷阱" class="headerlink" title="第 5 课 —— 表达式中的陷阱"></a>第 5 课 —— 表达式中的陷阱</h2><h3 id="关于字符串的陷阱"><a href="#关于字符串的陷阱" class="headerlink" title="关于字符串的陷阱"></a>关于字符串的陷阱</h3><h4 id="JVM-对字符串的处理"><a href="#JVM-对字符串的处理" class="headerlink" title="JVM 对字符串的处理"></a>JVM 对字符串的处理</h4><p><code>String java = new String(&quot;Java&quot;)</code> 这句创建了两个字符串对象，一个是 “Java” 这个直接量对应的字符串对象，另外一个是 new String() 构造器返回的字符串对象。</p>
<p>Java 程序中创建对象的方法：</p>
<ul>
<li>通过 new 调用构造器创建 Java 对象</li>
<li>通过 Class 对象的 newInstance() 方法调用构造器创建 Java 对象</li>
<li>通过 Java 的反序列化机制从 IO 流中恢复 Java 对象</li>
<li>通过 Java 对象提供的 clone() 方法复制一个新的 Java 对象</li>
<li>对于字符串以及 Byte、Short、Int、Long、Character、Float、Double 和 Boolean 这些基本类型的包装类</li>
<li>直接量的方式来创建 Java 对象  Integer in = 5；</li>
<li>通过简单的算法表达式，连接运算来创建 Java 对象 String str = “a” + “b”; （如果这个字符串表达式的值在编译时确定下来，那么 JVM 会在编译时计算该字符串变量的值，并让它指向字符串池中对应的字符串。如果这些算法表达式都是字符串直接量、整数直接量，没有变量和方法参与，那么就可以在编译期就可以确定字符串的值；如果使用了变量、调用了方法，那么只有等到运行时才能确定字符串表达式的值；如果字符串连接运算所有的变量都可执行 “宏替换”（使用 final 修饰的变量），那在编译时期也能确定字符串连接表达式的值）</li>
</ul>
<p>对于 Java 程序的字符直接量，JVM 会使用一个字符串池来保护它们；当第一次使用某个字符串直接量时，JVM 会将它放入字符串池进行缓存。在一般的情况下，字符串池中的字符串对象不会被垃圾回收器回收，当程序再次需要使用该字符串时，无需重新创建一个新的字符串，而是直接让引用变量指向字符串池中已有的字符串。</p>
<h4 id="不可变的字符串"><a href="#不可变的字符串" class="headerlink" title="不可变的字符串"></a>不可变的字符串</h4><p>String 类是一个不可变类，当一个 String 对象创建完成后，该 String 类里包含的字符序列就被固定下来，以后永远不能修改。</p>
<p>如果程序需要一个字符序列会发生改变的字符串，那么建议使用 StringBuilder （效率比 StringBuffer 高）</p>
<h4 id="字符串比较"><a href="#字符串比较" class="headerlink" title="字符串比较"></a>字符串比较</h4><p>如果要比较两个字符串是否相同，用 == 进行判断就行，但如果要判断两个字符串所包含的字符序列是否相同，则应该用 String 重写过的 equals() 方法进行比较。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">equals</span><span class="params">(Object anObject)</span> </span>&#123;</span><br><span class="line">        <span class="comment">//如果两个字符串相同</span></span><br><span class="line">        <span class="keyword">if</span> (<span class="keyword">this</span> == anObject) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="comment">//如果anObject是String类型</span></span><br><span class="line">        <span class="keyword">if</span> (anObject <span class="keyword">instanceof</span> String) &#123;</span><br><span class="line">            String anotherString = (String)anObject;</span><br><span class="line">            <span class="comment">//n代表字符串的长度</span></span><br><span class="line">            <span class="keyword">int</span> n = value.length;</span><br><span class="line">            <span class="comment">//如果两个字符串长度相等</span></span><br><span class="line">            <span class="keyword">if</span> (n == anotherString.value.length) &#123;</span><br><span class="line">                <span class="comment">//获取当前字符串、anotherString底层封装的字符数组</span></span><br><span class="line">                <span class="keyword">char</span> v1[] = value;</span><br><span class="line">                <span class="keyword">char</span> v2[] = anotherString.value;</span><br><span class="line">                <span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line">                <span class="comment">//逐一比较v1 和 v2数组中的每个字符</span></span><br><span class="line">                <span class="keyword">while</span> (n-- != <span class="number">0</span>) &#123;</span><br><span class="line">                    <span class="keyword">if</span> (v1[i] != v2[i])</span><br><span class="line">                        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">                    i++;</span><br><span class="line">                &#125;</span><br><span class="line">                <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>
<p>还可以使用 String 提供的 compareTo() 方法返回两个字符串的大小</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">compareTo</span><span class="params">(String anotherString)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">int</span> len1 = value.length;</span><br><span class="line">        <span class="keyword">int</span> len2 = anotherString.value.length;</span><br><span class="line">        <span class="keyword">int</span> lim = Math.min(len1, len2);</span><br><span class="line">        <span class="keyword">char</span> v1[] = value;</span><br><span class="line">        <span class="keyword">char</span> v2[] = anotherString.value;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">int</span> k = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">while</span> (k &lt; lim) &#123;</span><br><span class="line">            <span class="keyword">char</span> c1 = v1[k];</span><br><span class="line">            <span class="keyword">char</span> c2 = v2[k];</span><br><span class="line">            <span class="keyword">if</span> (c1 != c2) &#123;</span><br><span class="line">                <span class="keyword">return</span> c1 - c2;</span><br><span class="line">            &#125;</span><br><span class="line">            k++;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">return</span> len1 - len2;</span><br><span class="line">    &#125;</span><br></pre></td></tr></table></figure>
<h3 id="表达式类型的陷阱"><a href="#表达式类型的陷阱" class="headerlink" title="表达式类型的陷阱"></a>表达式类型的陷阱</h3><h4 id="表达式类型的自动提升"><a href="#表达式类型的自动提升" class="headerlink" title="表达式类型的自动提升"></a>表达式类型的自动提升</h4><ul>
<li><p>所有 byte、short、char类型将被提升到 int 类型参与运算</p>
</li>
<li><p>整个算术表达式的数据类型自动提升到与表达式中最高等级操作数同样的类型，操作数的等级排列如下：char -&gt; int -&gt; long -&gt;float -&gt; double</p>
<p>byte -&gt; short -&gt; int -&gt; long -&gt;float -&gt; double</p>
</li>
</ul>
<h4 id="复合赋值运算符的陷阱"><a href="#复合赋值运算符的陷阱" class="headerlink" title="复合赋值运算符的陷阱"></a>复合赋值运算符的陷阱</h4><p>Java 语言允许所有的双目运算符和 = 一起结合组成复合赋值运算符，如 +=、-=、*=、/=、%= 、&amp;= 等，复合赋值运算符包含了一个隐式的类型转换。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//下面这两条语句不等价</span></span><br><span class="line">a = a + <span class="number">5</span>;		<span class="comment">//</span></span><br><span class="line">a += <span class="number">5</span>;			<span class="comment">//实际上等价于 a = (a的类型) (a + 5);</span></span><br></pre></td></tr></table></figure>
<p>复合赋值运算符会自动的将它计算的结果值强制转换为其左侧变量的类型。</p>
<h3 id="输入法导致的陷阱"><a href="#输入法导致的陷阱" class="headerlink" title="输入法导致的陷阱"></a>输入法导致的陷阱</h3><h3 id="注释的字符必须合法"><a href="#注释的字符必须合法" class="headerlink" title="注释的字符必须合法"></a>注释的字符必须合法</h3><h3 id="转义字符的陷阱"><a href="#转义字符的陷阱" class="headerlink" title="转义字符的陷阱"></a>转义字符的陷阱</h3><ul>
<li>慎用字符的 Unicode 转义形式</li>
<li>中止行注释的转义字符</li>
</ul>
<h3 id="泛型可能引起的错误"><a href="#泛型可能引起的错误" class="headerlink" title="泛型可能引起的错误"></a>泛型可能引起的错误</h3><h4 id="原始类型变量的赋值"><a href="#原始类型变量的赋值" class="headerlink" title="原始类型变量的赋值"></a>原始类型变量的赋值</h4><ul>
<li>当程序把一个原始类型的变量赋给一个带有泛型信息的变量时，总是可以通过编译（只是会提示警告信息）</li>
<li>当程序试图访问带泛型声明的集合的集合元素时，编译器总是把集合元素当成泛型类型处理（它并不关心集合里集合元素的实际类型）</li>
<li>当程序试图访问带泛型声明的集合的集合元素时，JVM会遍历每个集合元素自动执行强制转型，如果集合元素的实际类型与集合所带的泛型信息不匹配，运行时将引发 ClassCastException</li>
</ul>
<h4 id="原始类型带来的擦除"><a href="#原始类型带来的擦除" class="headerlink" title="原始类型带来的擦除"></a>原始类型带来的擦除</h4><p>当把一个具有泛型信息的对象赋给另一个没有泛型信息的变量时，所有在尖括号之间的类型信息都会丢弃。</p>
<h4 id="创建泛型数组的陷阱"><a href="#创建泛型数组的陷阱" class="headerlink" title="创建泛型数组的陷阱"></a>创建泛型数组的陷阱</h4><p>Java 中不允许创建泛型数组</p>
<h3 id="正则表达式的陷阱"><a href="#正则表达式的陷阱" class="headerlink" title="正则表达式的陷阱"></a>正则表达式的陷阱</h3><p>有些符号本身就是正则表达式，我们需要对符号做转义运算。</p>
<h3 id="多线程的陷阱"><a href="#多线程的陷阱" class="headerlink" title="多线程的陷阱"></a>多线程的陷阱</h3><h4 id="不要调用-run-方法"><a href="#不要调用-run-方法" class="headerlink" title="不要调用 run 方法"></a>不要调用 run 方法</h4><p>开启线程是用 start() 方法，而不是 run() 方法。</p>
<h4 id="静态的同步方法"><a href="#静态的同步方法" class="headerlink" title="静态的同步方法"></a>静态的同步方法</h4><p>对于同步代码块而言，程序必须显式为它指定同步监视器；对于同步非静态方法而言，该方法的同步监视器是 this —— 即调用该方法的 Java 对象；对于静态的同步方法而言，该方法的同步监视器不是 this，而是该类本身。</p>
<h2 id="第-6-课-——-流程控制的陷阱"><a href="#第-6-课-——-流程控制的陷阱" class="headerlink" title="第 6 课 —— 流程控制的陷阱"></a>第 6 课 —— 流程控制的陷阱</h2><h3 id="switch-语句陷阱"><a href="#switch-语句陷阱" class="headerlink" title="switch 语句陷阱"></a>switch 语句陷阱</h3><p>break 语句不要忘记写</p>
<p>switch 的表达式类型：</p>
<ul>
<li>byte</li>
<li>short</li>
<li>int</li>
<li>char</li>
<li>enum</li>
<li>String （Jdk 1.7 以后有 String）</li>
</ul>
<h3 id="标签引起的陷阱"><a href="#标签引起的陷阱" class="headerlink" title="标签引起的陷阱"></a>标签引起的陷阱</h3><p>Java 中的标签通常是和循环中的 break 和 continue 结合使用，让 break 直接终止标签所标识的循环，让 continue 语句忽略标签所标识的循环的剩下语句。</p>
<p>。。</p>
<h2 id="第-7-课-——-面向对象的陷阱"><a href="#第-7-课-——-面向对象的陷阱" class="headerlink" title="第 7 课 —— 面向对象的陷阱"></a>第 7 课 —— 面向对象的陷阱</h2><h3 id="instanceof-运算符的陷阱"><a href="#instanceof-运算符的陷阱" class="headerlink" title="instanceof  运算符的陷阱"></a>instanceof  运算符的陷阱</h3><p>instanceof 它用于判断前面的对象是否是后面的类或其子类、实现类的实例。如果是返回 true，否则返回 false。</p>
<p>instanceof 运算符前面操作数的编译时类型必须是：</p>
<ul>
<li>要么与后面的类相同</li>
<li>要么是后面类的父类</li>
<li>要么是后面类型的子类</li>
</ul>
<h3 id="构造器陷阱"><a href="#构造器陷阱" class="headerlink" title="构造器陷阱"></a>构造器陷阱</h3><p>构造器是 Java 中每个类都会提供的一个“特殊方法”。构造器负责对 Java 对象执行初始化操作，不管是定义实例变量时指定的初始值，还是在非静态初始化代码块中所做的操作，实际上都会被提取到构造器中执行。</p>
<p>构造器不能声明返回值类型，也不能使用void声明构造器没有返回值。</p>
<h4 id="构造器创建对象吗"><a href="#构造器创建对象吗" class="headerlink" title="构造器创建对象吗"></a>构造器创建对象吗</h4><p>构造器并不会创建 Java 对象，构造器只是负责执行初始化，在构造器执行之前，Java 对象所需要的内存空间，是由 new 关键字申请出来的。绝大部分时候，程序使用 new 关键字为一个 Java 对象申请空间之后，都需要使用构造器为这个对象执行初始化，但在某些时候，程序创建 Java 对象无需调用构造器，如下：</p>
<ul>
<li>使用反序列化的方式恢复 Java 对象</li>
<li>使用 clone 方法复制 Java 对象</li>
</ul>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">package</span> com.zhisheng.test;</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> java.io.*;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * Created by 10412 on 2017/5/31.</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Wolf</span> <span class="keyword">implements</span> <span class="title">Serializable</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="keyword">private</span> String name;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">Wolf</span><span class="params">(String name)</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"调用了有参构造方法"</span>);</span><br><span class="line">        <span class="keyword">this</span>.name = name;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">equals</span><span class="params">(Object o)</span> </span>&#123;</span><br><span class="line">        <span class="keyword">if</span> (<span class="keyword">this</span> == o) <span class="keyword">return</span> <span class="keyword">true</span>;</span><br><span class="line">        <span class="keyword">if</span> (o == <span class="keyword">null</span> || getClass() != o.getClass()) <span class="keyword">return</span> <span class="keyword">false</span>;</span><br><span class="line"></span><br><span class="line">        Wolf wolf = (Wolf) o;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> name != <span class="keyword">null</span> ? name.equals(wolf.name) : wolf.name == <span class="keyword">null</span>;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="meta">@Override</span></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">hashCode</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> name != <span class="keyword">null</span> ? name.hashCode() : <span class="number">0</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">SerializableTest</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        Wolf w = <span class="keyword">new</span> Wolf(<span class="string">"灰太狼"</span>);</span><br><span class="line">        System.out.println(<span class="string">"对象创建完成"</span>);</span><br><span class="line">        Wolf w2 = <span class="keyword">null</span>;</span><br><span class="line">        ObjectInputStream ois = <span class="keyword">null</span>;</span><br><span class="line">        ObjectOutputStream oos = <span class="keyword">null</span>;</span><br><span class="line">        <span class="keyword">try</span> &#123;</span><br><span class="line">            <span class="comment">//创建输出对象流</span></span><br><span class="line">            oos = <span class="keyword">new</span> ObjectOutputStream(<span class="keyword">new</span> FileOutputStream(<span class="string">"a.bin"</span>));</span><br><span class="line">            <span class="comment">//创建输入对象流</span></span><br><span class="line">            ois = <span class="keyword">new</span> ObjectInputStream(<span class="keyword">new</span> FileInputStream(<span class="string">"a.bin"</span>));</span><br><span class="line">            <span class="comment">//序列输出java 对象</span></span><br><span class="line">            oos.writeObject(w);</span><br><span class="line">            oos.flush();</span><br><span class="line">            <span class="comment">//反序列化恢复java对象</span></span><br><span class="line">            w2 = (Wolf) ois.readObject();</span><br><span class="line">            System.out.println(w);</span><br><span class="line">            System.out.println(w2);</span><br><span class="line">            <span class="comment">//两个对象的实例变量值完全相等，输出true</span></span><br><span class="line">            System.out.println(w.equals(w2));</span><br><span class="line">            <span class="comment">//两个对象不同，输出false</span></span><br><span class="line">            System.out.println(w == w2);</span><br><span class="line">        &#125; <span class="keyword">catch</span> (IOException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125; <span class="keyword">catch</span> (ClassNotFoundException e) &#123;</span><br><span class="line">            e.printStackTrace();</span><br><span class="line">        &#125;<span class="keyword">finally</span> &#123;</span><br><span class="line">            <span class="keyword">if</span> (ois!=<span class="keyword">null</span>)</span><br><span class="line">                <span class="keyword">try</span> &#123;</span><br><span class="line">                    ois.close();</span><br><span class="line">                &#125; <span class="keyword">catch</span> (IOException e) &#123;</span><br><span class="line">                    e.printStackTrace();</span><br><span class="line">                &#125;</span><br><span class="line">            <span class="keyword">if</span> (oos!=<span class="keyword">null</span>)</span><br><span class="line">                <span class="keyword">try</span> &#123;</span><br><span class="line">                    oos.close();</span><br><span class="line">                &#125; <span class="keyword">catch</span> (IOException e) &#123;</span><br><span class="line">                    e.printStackTrace();</span><br><span class="line">                &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>程序运行结果：</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">调用了有参构造方法</span><br><span class="line">对象创建完成</span><br><span class="line">com.zhisheng.test.Wolf@<span class="number">1</span>b15382</span><br><span class="line">com.zhisheng.test.Wolf@<span class="number">1</span>b15382</span><br><span class="line"><span class="keyword">true</span></span><br><span class="line"><span class="keyword">false</span></span><br></pre></td></tr></table></figure>
<p>正如结果所示：创建 Wolf 对象时，程序调用了相应的构造器来对该对象执行初始化；当程序通过反序列化机制恢复 Java 对象时，系统无需在调用构造器来进行初始化。通过反序列化恢复出来的 Wolf 对象和原来的 Wolf 对象具有完全相同的实例变量值，但系统会产生两个对象。</p>
<h4 id="无限递归构造器"><a href="#无限递归构造器" class="headerlink" title="无限递归构造器"></a>无限递归构造器</h4><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">ConstrutionTest</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    ConstrutionTest ct;</span><br><span class="line">    &#123;</span><br><span class="line">        ct = <span class="keyword">new</span> ConstrutionTest();</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="title">ConstrutionTest</span><span class="params">()</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"无参构造器"</span>);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        ConstrutionTest ct = <span class="keyword">new</span> ConstrutionTest();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>运行结果抛出异常 <code>java.lang.StackOverflowError</code></p>
<p>因为不管定义实例变量时指定的初始值，还是在非静态初始化代码块中执行的初始化操作，最终都将提取到构造器中执行，因为代码中递归调用了类的构造器，最终导致出现 <code>java.lang.StackOverflowError</code> 异常。</p>
<h3 id="到底调用哪个重载方法"><a href="#到底调用哪个重载方法" class="headerlink" title="到底调用哪个重载方法"></a>到底调用哪个重载方法</h3><p>1、第一阶段 JVM 将会选取所有可获得并匹配调用的方法或者构造器</p>
<p>2、第二个阶段决定到底要调用哪个方法，此时 JVM 会在第一阶段所选取的方法或者构造器中再次选取最精确匹配的那一个。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">OverrideTest</span></span></span><br><span class="line"><span class="class"></span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">info</span><span class="params">(Object obj, <span class="keyword">int</span> a)</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"obj 参数"</span> + obj);</span><br><span class="line">        System.out.println(<span class="string">"整型参数 "</span> + a);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">info</span><span class="params">(Object[] obj, <span class="keyword">double</span> a)</span> </span>&#123;</span><br><span class="line">        System.out.println(<span class="string">"obj 参数"</span> + obj);</span><br><span class="line">        System.out.println(<span class="string">"整型参数 "</span> + a);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>&#123;</span><br><span class="line">        OverrideTest o = <span class="keyword">new</span> OverrideTest();</span><br><span class="line">        o.info(<span class="keyword">null</span>, <span class="number">5</span>);</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>报错如下：</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Error:(20, 10) java: 对info的引用不明确</span><br><span class="line">  com.zhisheng.test.OverrideTest 中的方法 info(java.lang.Object,int) 和 com.zhisheng.test.OverrideTest 中的方法 info(java.lang.Object[],double) 都匹配</span><br></pre></td></tr></table></figure>
<p>在这种复杂的条件下，JVM 无法判断哪个方法更匹配实际调用，将会导致程序编译错误。</p>
<h3 id="方法重写的陷阱"><a href="#方法重写的陷阱" class="headerlink" title="方法重写的陷阱"></a>方法重写的陷阱</h3><p>无法重写父类 private 方法。如果子类有一个与父类 private 方法具有相同方法名、相同形参列表、相同返回值类型的方法，依然不是重写，只是子类定义了一个与父类相同的方法。</p>
<h3 id="static-关键字"><a href="#static-关键字" class="headerlink" title="static 关键字"></a>static 关键字</h3><p>static 可以修饰类中定义的成员：field、方法、内部类、初始化代码块、内部枚举类</p>
<h4 id="静态方法属于类"><a href="#静态方法属于类" class="headerlink" title="静态方法属于类"></a>静态方法属于类</h4><p>被 static 修饰的成员（field、方法、内部类、初始化块、内部枚举类）属于类本身，而不是单个的 Java 对象。静态方法也是属于类。</p>
<h2 id="第-8-课-——-异常捕捉的陷阱"><a href="#第-8-课-——-异常捕捉的陷阱" class="headerlink" title="第 8 课 —— 异常捕捉的陷阱"></a>第 8 课 —— 异常捕捉的陷阱</h2><h3 id="正确关闭资源的方式"><a href="#正确关闭资源的方式" class="headerlink" title="正确关闭资源的方式"></a>正确关闭资源的方式</h3><ul>
<li>使用 finally 块来保证回收，保证关闭操作总是会被执行</li>
<li>关闭每个资源之前首先保证引用该资源的引用变量不为 null</li>
<li>为每个物理资源单独使用 try .. catch 块关闭资源，保证关闭资源时引发的异常不会影响其他资源的关闭。</li>
</ul>
<h3 id="finally-块陷阱"><a href="#finally-块陷阱" class="headerlink" title="finally 块陷阱"></a>finally 块陷阱</h3><p>finally 执行顺序，看我以前写的一篇文章<a href="http://www.54tianzhisheng.cn/2017/03/28/%E6%B7%B1%E5%BA%A6%E6%8E%A2%E7%A9%B6Java%20%E4%B8%AD%20finally%20%E8%AF%AD%E5%8F%A5%E5%9D%97/">《深度探究Java 中 finally 语句块》</a>。</p>
<h3 id="catch-块用法"><a href="#catch-块用法" class="headerlink" title="catch 块用法"></a>catch 块用法</h3><p>在 try 块后使用 catch 块来捕获多个异常时，程序应该小心多个 catch 块之间的顺序：捕获父类异常的 catch 块都应该排在捕获子类异常的 catch 块之后（先处理小异常，再处理大异常），否则出现编译错误。</p>
<h3 id="继承得到的异常"><a href="#继承得到的异常" class="headerlink" title="继承得到的异常"></a>继承得到的异常</h3><p>子类重写父类方法时，不能声明抛出比父类方法类型更多、范围更大的异常。</p>
<p>二叉树性质：</p>
<ul>
<li><p>二叉树第 i 层上的节点数目至多为 2 ^(i - 1)   (i &gt;= 1)</p>
</li>
<li><p>深度为 k 的二叉树至多有 2 ^ k - 1 个节点</p>
</li>
<li><p>在任何一颗二叉树中，如果其叶子结点的数量为 n0，度为 2 的子节点数量为 n2，则 n0 = n2 + 1</p>
</li>
<li><p>具有 n 个节点的完全二叉树的深度为 log n   +  1   (log 的底为 2)</p>
</li>
<li><p>对于一棵有 n 个节点的完全二叉树的节点按层自左向右编号，则对任一编号为 i 的节点有如下性质：</p>
<p>当 i == 1 时，节点 i 是二叉树的根；若 i &gt; 1 时，则节点的父节点是 i/2</p>
<p>当 2i &lt;= n，则节点 i 有左孩子，左孩子的编号是 2i，否则，节点无左孩子，并且是叶子结点</p>
<p>若 2i + 1 &lt;= n ，则节点 i 有右孩子，右孩子的编号是 2i + 1；否则，节点无右孩子。</p>
</li>
<li><p>对于一颗 n 个节点的完全二叉树的节点按层自左向右编号，1 ~ n/2 范围的节点都是有孩子节点的非叶子结点，其余的节点全部都是叶子结点。编号为 n/2 的节点有可能只有左节点，也可能既有左节点，又有右节点。</p>
</li>
</ul>
<h3 id="选择排序"><a href="#选择排序" class="headerlink" title="选择排序"></a>选择排序</h3><h4 id="直接选择排序"><a href="#直接选择排序" class="headerlink" title="直接选择排序"></a>直接选择排序</h4><p>需要经过 n - 1 趟比较</p>
<p>第一趟比较：程序将记录定位在第一个数据上，拿第一个数据依次和它后面的每个数据进行比较，如果第一个数据大于后面某个数据，交换它们。。依此类推，经过第一趟比较，这组数据中最小的数据被选出来，它被排在第一位。</p>
<p>第二趟比较：程序将记录定位在第二个数据上，拿第二个数据依次和它后面每个数据进行比较，如果第二个数据大于后面某个数据，交换它们。。依次类推，经过第二趟比较，这组数据中第二小的数据被选出，它排在第二位</p>
<p>。。</p>
<p>按此规则一共进行 n-1 趟比较，这组数据中第 n - 1小（第二大）的数据被选出，被排在第 n -1 位（倒数第一位）；剩下的就是最大的数据，它排在最后。</p>
<p>直接选择排序的优点就是算法简单，容易实现，缺点就是每趟只能确定一个元素，n个数组需要进行 n-1 趟比较。</p>
<h4 id="堆排序"><a href="#堆排序" class="headerlink" title="堆排序"></a>堆排序</h4><ul>
<li>建堆</li>
<li>拿堆的根节点和最后一个节点交换</li>
</ul>
<h3 id="交换排序"><a href="#交换排序" class="headerlink" title="交换排序"></a>交换排序</h3><h4 id="冒泡排序"><a href="#冒泡排序" class="headerlink" title="冒泡排序"></a>冒泡排序</h4><p>第一趟：依次比较0和1，1和2，2和3 … n-2 和 n - 1 索引的元素，如果发现第一个数据大于后一个数据，交换它们，经过第一趟，最大的元素排到了最后。</p>
<p>第二趟：依次比较0和1，1和2，2和3 … n-3 和 n - 2 索引的元素，如果发现第一个数据大于后一个数据，交换它们，经过第二趟，第二大的元素排到了倒数第二位</p>
<p>。。</p>
<p>第 n -1 趟：依次比较0和1元素，如果发现第一个数据大于后一个数据，交换它们，经过第 n - 1 趟，第二小的元素排到了第二位。</p>
<h4 id="快速排序"><a href="#快速排序" class="headerlink" title="快速排序"></a>快速排序</h4><p>从待排的数据序列中任取一个数据作为分界值，所有比它小的数据元素一律放在左边，所有比他大的元素一律放在右边，这样一趟下来，该序列就分成了两个子序列，接下来对两个子序列进行递归，直到每个子序列只剩一个，排序完成。</p>
<h3 id="插入排序"><a href="#插入排序" class="headerlink" title="插入排序"></a>插入排序</h3><h4 id="直接插入排序"><a href="#直接插入排序" class="headerlink" title="直接插入排序"></a>直接插入排序</h4><p>依次将待排序的数据元素按其关键字值的大小插入前面的有序序列。</p>
<h4 id="折半插入排序"><a href="#折半插入排序" class="headerlink" title="折半插入排序"></a>折半插入排序</h4><p>当第 i - 1 趟需要将第 i 个元素插入前面的 0 ~ i -1 个元素序列中时：</p>
<ul>
<li>计算 0 ~ i - 1 索引的中间点，也就是用 i 索引处的元素和 （0 + i - 1）/2 索引处的元素进行比较，如果 i 索引处的元素大，就直接在 （（0 + i - 1）/2 ） ~ （i - 1）后半个范围内进行搜索，反之在前半个范围搜索。</li>
<li>重复上面步骤</li>
<li>确定第 i 个元素的插入位置，就将该位置的后面所有元素整体后移一位，然后将第 i 个元素放入该位置。</li>
</ul>
<p><img src="https://ws3.sinaimg.cn/large/006tNc79gy1fp3jkmizmpj30o00didgn.jpg" alt=""></p>

      
      
        <div class="page-reward">
          <p><a href="javascript:void(0)" onclick="dashangToggle()" class="dashang">赏</a></p>
          <div class="hide_box"></div>
          <div class="shang_box">
            <a class="shang_close" href="javascript:void(0)" onclick="dashangToggle()">×</a>
            <div class="shang_tit">
              <p>纯属好玩</p>
            </div>
            <div class="shang_payimg">
              <img src="/img/alipayimg.jpg" alt="扫码支持" title="扫一扫" />
            </div>
              <div class="pay_explain">扫码打赏，你说多少就多少</div>
            <div class="shang_payselect">
              
                <div class="pay_item checked" data-id="alipay">
                  <span class="radiobox"></span>
                  <span class="pay_logo"><img src="/img/alipay.png" alt="支付宝" /></span>
                </div>
              
              
                <div class="pay_item" data-id="wechat">
                  <span class="radiobox"></span>
                  <span class="pay_logo"><img src="/img/weixin.png" alt="微信" /></span>
                </div>
              
            </div>
            <div class="shang_info">
              <p>打开<span id="shang_pay_txt">支付宝</span>扫一扫，即可进行扫码打赏哦</p>
            </div>
          </div>
        </div>
        <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/zepto/1.2.0/zepto.min.js"></script>
        <script type="text/javascript">
          $(".pay_item").click(function(){
            $(this).addClass('checked').siblings('.pay_item').removeClass('checked');
            var dataid=$(this).attr('data-id');
            $(".shang_payimg img").attr("src","/img/"+dataid+"img.jpg");
            $("#shang_pay_txt").text(dataid=="alipay"?"支付宝":"微信");
          });
          function dashangToggle(){
            
            $(".hide_box").fadeToggle();
            $(".shang_box").fadeToggle();
          }
        </script>
      
    </div>
    
  </div>
  
    
    <div class="copyright">
        <p><span>本文标题:</span><a href="/2017/06/13/Java-16-lession/">《疯狂 Java 突破程序员基本功的 16 课》读书笔记</a></p>
        <p><span>文章作者:</span><a href="/" title="访问 zhisheng 的个人博客">zhisheng</a></p>
        <p><span>发布时间:</span>2017年06月13日 - 00时00分</p>
        <p><span>最后更新:</span>2018年11月22日 - 22时51分</p>
        <p>
            <span>原始链接:</span><a class="post-url" href="/2017/06/13/Java-16-lession/" title="《疯狂 Java 突破程序员基本功的 16 课》读书笔记">http://www.54tianzhisheng.cn/2017/06/13/Java-16-lession/</a>
            <span class="copy-path" data-clipboard-text="原文: http://www.54tianzhisheng.cn/2017/06/13/Java-16-lession/　　作者: zhisheng" title="点击复制文章链接"><i class="fa fa-clipboard"></i></span>
            <script src="/js/clipboard.min.js"></script>
            <script> var clipboard = new Clipboard('.copy-path'); </script>
        </p>
        <p>
            <span>许可协议:</span><i class="fa fa-creative-commons"></i> <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/3.0/cn/" title="中国大陆 (CC BY-NC-SA 3.0 CN)" target = "_blank">"署名-非商用-相同方式共享 3.0"</a> 转载请保留原文链接及作者。
        </p>
    </div>



<nav id="article-nav">
  
    <a href="/2017/06/13/JVM性能调优监控工具jps、jstack、jmap、jhat、jstat等使用详解/" id="article-nav-newer" class="article-nav-link-wrap">
      <strong class="article-nav-caption"><</strong>
      <div class="article-nav-title">
        
          JVM性能调优监控工具jps、jstack、jmap、jhat、jstat等使用详解
        
      </div>
    </a>
  
  
    <a href="/2017/06/13/奇怪的Java题：为什么128 == 128返回为False，而127 == 127会返回为True-/" id="article-nav-older" class="article-nav-link-wrap">
      <div class="article-nav-title">奇怪的Java题：为什么128 == 128返回为False，而127 == 127会返回为True?</div>
      <strong class="article-nav-caption">></strong>
    </a>
  
</nav>

  
</article>

    <div id="toc" class="toc-article">
    <strong class="toc-title">文章目录</strong>
    <ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#第-1-课-——-数组与内存控制"><span class="toc-number">1.</span> <span class="toc-text">第 1 课 —— 数组与内存控制</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#数组初始化"><span class="toc-number">1.1.</span> <span class="toc-text">数组初始化</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#使用数组"><span class="toc-number">1.2.</span> <span class="toc-text">使用数组</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第-2-课-——-对象与内存的控制"><span class="toc-number">2.</span> <span class="toc-text">第 2 课 —— 对象与内存的控制</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#实例变量-和-类变量"><span class="toc-number">2.1.</span> <span class="toc-text">实例变量 和 类变量</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#局部变量"><span class="toc-number">2.1.1.</span> <span class="toc-text">局部变量</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#成员变量"><span class="toc-number">2.1.2.</span> <span class="toc-text">成员变量</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#实例变量和类变量的属性"><span class="toc-number">2.1.3.</span> <span class="toc-text">实例变量和类变量的属性</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#实例变量的初始化时机"><span class="toc-number">2.1.4.</span> <span class="toc-text">实例变量的初始化时机</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#类变量的初始化时机"><span class="toc-number">2.1.5.</span> <span class="toc-text">类变量的初始化时机</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#父类构造器"><span class="toc-number">2.2.</span> <span class="toc-text">父类构造器</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#隐式调用和显示调用"><span class="toc-number">2.2.1.</span> <span class="toc-text">隐式调用和显示调用</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#访问子类对象的实例变量"><span class="toc-number">2.2.2.</span> <span class="toc-text">访问子类对象的实例变量</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#调用被子类重写的方法"><span class="toc-number">2.2.3.</span> <span class="toc-text">调用被子类重写的方法</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#父子实例的内存控制"><span class="toc-number">2.3.</span> <span class="toc-text">父子实例的内存控制</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#继承成员变量和继承方法的区别"><span class="toc-number">2.3.1.</span> <span class="toc-text">继承成员变量和继承方法的区别</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#内存中的子类实例"><span class="toc-number">2.3.2.</span> <span class="toc-text">内存中的子类实例</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#父、子类的类变量"><span class="toc-number">2.3.3.</span> <span class="toc-text">父、子类的类变量</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#final-修饰符"><span class="toc-number">2.4.</span> <span class="toc-text">final 修饰符</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第-3-课-——-常见-Java-集合的实现细节"><span class="toc-number">3.</span> <span class="toc-text">第 3 课 —— 常见 Java 集合的实现细节</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Set-和-Map"><span class="toc-number">3.1.</span> <span class="toc-text">Set 和 Map</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#Set-和-Map-的关系"><span class="toc-number">3.1.1.</span> <span class="toc-text">Set 和 Map 的关系</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#HashMap-和-HashSet"><span class="toc-number">3.1.2.</span> <span class="toc-text">HashMap 和 HashSet</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#TreeMap-和-TreeSet"><span class="toc-number">3.1.3.</span> <span class="toc-text">TreeMap 和 TreeSet</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Map-和-List"><span class="toc-number">3.2.</span> <span class="toc-text">Map 和 List</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#Map-的-values-方法"><span class="toc-number">3.2.1.</span> <span class="toc-text">Map 的 values() 方法</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#Map-和-List-的关系"><span class="toc-number">3.2.2.</span> <span class="toc-text">Map 和 List 的关系</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#ArrayList-和-LinkedList"><span class="toc-number">3.3.</span> <span class="toc-text">ArrayList 和 LinkedList</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Iterator-迭代器"><span class="toc-number">3.4.</span> <span class="toc-text">Iterator 迭代器</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第-4-课-——-Java-的内存回收"><span class="toc-number">4.</span> <span class="toc-text">第 4 课 —— Java 的内存回收</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Java-引用的种类"><span class="toc-number">4.1.</span> <span class="toc-text">Java 引用的种类</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#对象在内存中的状态"><span class="toc-number">4.1.1.</span> <span class="toc-text">对象在内存中的状态</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#强引用"><span class="toc-number">4.1.2.</span> <span class="toc-text">强引用</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#软引用"><span class="toc-number">4.1.3.</span> <span class="toc-text">软引用</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#弱引用"><span class="toc-number">4.1.4.</span> <span class="toc-text">弱引用</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#虚引用"><span class="toc-number">4.1.5.</span> <span class="toc-text">虚引用</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Java-的内存泄漏"><span class="toc-number">4.2.</span> <span class="toc-text">Java 的内存泄漏</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#垃圾回收机制"><span class="toc-number">4.3.</span> <span class="toc-text">垃圾回收机制</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#垃圾回收的基本算法"><span class="toc-number">4.3.1.</span> <span class="toc-text">垃圾回收的基本算法</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#堆内存的分代回收"><span class="toc-number">4.3.2.</span> <span class="toc-text">堆内存的分代回收</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#内存管理小技巧"><span class="toc-number">4.4.</span> <span class="toc-text">内存管理小技巧</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第-5-课-——-表达式中的陷阱"><span class="toc-number">5.</span> <span class="toc-text">第 5 课 —— 表达式中的陷阱</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#关于字符串的陷阱"><span class="toc-number">5.1.</span> <span class="toc-text">关于字符串的陷阱</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#JVM-对字符串的处理"><span class="toc-number">5.1.1.</span> <span class="toc-text">JVM 对字符串的处理</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#不可变的字符串"><span class="toc-number">5.1.2.</span> <span class="toc-text">不可变的字符串</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#字符串比较"><span class="toc-number">5.1.3.</span> <span class="toc-text">字符串比较</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#表达式类型的陷阱"><span class="toc-number">5.2.</span> <span class="toc-text">表达式类型的陷阱</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#表达式类型的自动提升"><span class="toc-number">5.2.1.</span> <span class="toc-text">表达式类型的自动提升</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#复合赋值运算符的陷阱"><span class="toc-number">5.2.2.</span> <span class="toc-text">复合赋值运算符的陷阱</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#输入法导致的陷阱"><span class="toc-number">5.3.</span> <span class="toc-text">输入法导致的陷阱</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#注释的字符必须合法"><span class="toc-number">5.4.</span> <span class="toc-text">注释的字符必须合法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#转义字符的陷阱"><span class="toc-number">5.5.</span> <span class="toc-text">转义字符的陷阱</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#泛型可能引起的错误"><span class="toc-number">5.6.</span> <span class="toc-text">泛型可能引起的错误</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#原始类型变量的赋值"><span class="toc-number">5.6.1.</span> <span class="toc-text">原始类型变量的赋值</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#原始类型带来的擦除"><span class="toc-number">5.6.2.</span> <span class="toc-text">原始类型带来的擦除</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#创建泛型数组的陷阱"><span class="toc-number">5.6.3.</span> <span class="toc-text">创建泛型数组的陷阱</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#正则表达式的陷阱"><span class="toc-number">5.7.</span> <span class="toc-text">正则表达式的陷阱</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#多线程的陷阱"><span class="toc-number">5.8.</span> <span class="toc-text">多线程的陷阱</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#不要调用-run-方法"><span class="toc-number">5.8.1.</span> <span class="toc-text">不要调用 run 方法</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#静态的同步方法"><span class="toc-number">5.8.2.</span> <span class="toc-text">静态的同步方法</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第-6-课-——-流程控制的陷阱"><span class="toc-number">6.</span> <span class="toc-text">第 6 课 —— 流程控制的陷阱</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#switch-语句陷阱"><span class="toc-number">6.1.</span> <span class="toc-text">switch 语句陷阱</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#标签引起的陷阱"><span class="toc-number">6.2.</span> <span class="toc-text">标签引起的陷阱</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第-7-课-——-面向对象的陷阱"><span class="toc-number">7.</span> <span class="toc-text">第 7 课 —— 面向对象的陷阱</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#instanceof-运算符的陷阱"><span class="toc-number">7.1.</span> <span class="toc-text">instanceof  运算符的陷阱</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#构造器陷阱"><span class="toc-number">7.2.</span> <span class="toc-text">构造器陷阱</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#构造器创建对象吗"><span class="toc-number">7.2.1.</span> <span class="toc-text">构造器创建对象吗</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#无限递归构造器"><span class="toc-number">7.2.2.</span> <span class="toc-text">无限递归构造器</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#到底调用哪个重载方法"><span class="toc-number">7.3.</span> <span class="toc-text">到底调用哪个重载方法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#方法重写的陷阱"><span class="toc-number">7.4.</span> <span class="toc-text">方法重写的陷阱</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#static-关键字"><span class="toc-number">7.5.</span> <span class="toc-text">static 关键字</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#静态方法属于类"><span class="toc-number">7.5.1.</span> <span class="toc-text">静态方法属于类</span></a></li></ol></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第-8-课-——-异常捕捉的陷阱"><span class="toc-number">8.</span> <span class="toc-text">第 8 课 —— 异常捕捉的陷阱</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#正确关闭资源的方式"><span class="toc-number">8.1.</span> <span class="toc-text">正确关闭资源的方式</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#finally-块陷阱"><span class="toc-number">8.2.</span> <span class="toc-text">finally 块陷阱</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#catch-块用法"><span class="toc-number">8.3.</span> <span class="toc-text">catch 块用法</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#继承得到的异常"><span class="toc-number">8.4.</span> <span class="toc-text">继承得到的异常</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#选择排序"><span class="toc-number">8.5.</span> <span class="toc-text">选择排序</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#直接选择排序"><span class="toc-number">8.5.1.</span> <span class="toc-text">直接选择排序</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#堆排序"><span class="toc-number">8.5.2.</span> <span class="toc-text">堆排序</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#交换排序"><span class="toc-number">8.6.</span> <span class="toc-text">交换排序</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#冒泡排序"><span class="toc-number">8.6.1.</span> <span class="toc-text">冒泡排序</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#快速排序"><span class="toc-number">8.6.2.</span> <span class="toc-text">快速排序</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#插入排序"><span class="toc-number">8.7.</span> <span class="toc-text">插入排序</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#直接插入排序"><span class="toc-number">8.7.1.</span> <span class="toc-text">直接插入排序</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#折半插入排序"><span class="toc-number">8.7.2.</span> <span class="toc-text">折半插入排序</span></a></li></ol></li></ol></li></ol>
</div>
<input type="button" id="tocButton" value="隐藏目录"  title="点击按钮隐藏或者显示文章目录">

<script src="https://7.url.cn/edu/jslib/comb/require-2.1.6,jquery-1.9.1.min.js"></script>
<script>
    var valueHide = "隐藏目录";
    var valueShow = "显示目录";

    if ($(".left-col").is(":hidden")) {
        $("#tocButton").attr("value", valueShow);
    }
    $("#tocButton").click(function() {
        if ($("#toc").is(":hidden")) {
            $("#tocButton").attr("value", valueHide);
            $("#toc").slideDown(320);
        }
        else {
            $("#tocButton").attr("value", valueShow);
            $("#toc").slideUp(350);
        }
    })
    if ($(".toc").length < 1) {
        $("#toc, #tocButton").hide();
    }
</script>





<div class="bdsharebuttonbox">
	<a href="#" class="fx fa-weibo bds_tsina" data-cmd="tsina" title="分享到新浪微博"></a>
	<a href="#" class="fx fa-weixin bds_weixin" data-cmd="weixin" title="分享到微信"></a>
	<a href="#" class="fx fa-qq bds_sqq" data-cmd="sqq" title="分享到QQ好友"></a>
	<a href="#" class="fx fa-facebook-official bds_fbook" data-cmd="fbook" title="分享到Facebook"></a>
	<a href="#" class="fx fa-twitter bds_twi" data-cmd="twi" title="分享到Twitter"></a>
	<a href="#" class="fx fa-linkedin bds_linkedin" data-cmd="linkedin" title="分享到linkedin"></a>
	<a href="#" class="fx fa-files-o bds_copy" data-cmd="copy" title="分享到复制网址"></a>
</div>
<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"2","bdSize":"24"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>




    
        <div id="gitments"></div>
<script src="/js/gitment.browser.js"></script>
<script>
    var gitment = new Gitment({
      id: window.location.pathname,
      owner: 'zhisheng',
      repo: 'zhisheng17.github.io',
      oauth: {
        client_id: '',
        client_secret: '',
      },
    })
    gitment.render('gitments')
</script>
    



    <div class="scroll" id="post-nav-button">
        
            <a href="/2017/06/13/JVM性能调优监控工具jps、jstack、jmap、jhat、jstat等使用详解/" title="上一篇: JVM性能调优监控工具jps、jstack、jmap、jhat、jstat等使用详解">
                <i class="fa fa-angle-left"></i>
            </a>
        
        <a title="文章列表"><i class="fa fa-bars"></i><i class="fa fa-times"></i></a>
        
            <a href="/2017/06/13/奇怪的Java题：为什么128 == 128返回为False，而127 == 127会返回为True-/" title="下一篇: 奇怪的Java题：为什么128 == 128返回为False，而127 == 127会返回为True?">
                <i class="fa fa-angle-right"></i>
            </a>
        
    </div>
    <ul class="post-list"><li class="post-list-item"><a class="post-list-link" href="/2019/01/06/Flink-Kafka-sink/">《从0到1学习Flink》—— Flink 写入数据到 Kafka</a></li><li class="post-list-item"><a class="post-list-link" href="/2019/01/05/Flink-run/">《从0到1学习Flink》—— Flink 项目如何运行？</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/12/30/Flink-ElasticSearch-Sink/">《从0到1学习Flink》—— Flink 写入数据到 ElasticSearch</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/12/11/Flink-time/">《从0到1学习Flink》—— Flink 中几种 Time 详解</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/12/08/Flink-Stream-Windows/">《从0到1学习Flink》—— 介绍Flink中的Stream Windows</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/11/04/Flink-Data-transformation/">《从0到1学习Flink》—— Flink Data transformation(转换)</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/10/31/flink-create-sink/">《从0到1学习Flink》—— 如何自定义 Data Sink ？</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/10/30/flink-create-source/">《从0到1学习Flink》—— 如何自定义 Data Source ？</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/10/29/flink-sink/">《从0到1学习Flink》—— Data Sink 介绍</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/10/28/flink-sources/">《从0到1学习Flink》—— Data Source 介绍</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/10/27/flink-config/">《从0到1学习Flink》—— Flink 配置文件详解</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/10/13/flink-introduction/">《从0到1学习Flink》—— Apache Flink 介绍</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/09/18/flink-install/">《从0到1学习Flink》—— Mac 上搭建 Flink 1.6.0 环境并构建运行简单程序入门</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/08/30/go-sync/">Go 并发——实现协程同步的几种方式</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/08/14/idea-remote-debug-elasticsearch/">教你如何在 IDEA 远程 Debug ElasticSearch</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/08/12/es-code03/">渣渣菜鸡的 ElasticSearch 源码解析 —— 启动流程（下）</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/08/11/es-code02/">渣渣菜鸡的 ElasticSearch 源码解析 —— 启动流程（上）</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/08/05/es-code01/">渣渣菜鸡的 ElasticSearch 源码解析 —— 环境搭建</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/08/04/why-see-es-code/">渣渣菜鸡为什么要看 ElasticSearch 源码？</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/07/31/alipay02/">渣渣菜鸡的蚂蚁金服面试经历(二)</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/07/30/alipay01/">渣渣菜鸡的蚂蚁金服面试经历(一)</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/07/12/youzan/">渣渣菜鸡的有赞面试经历（一）</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/06/20/java-8-date/">20 个案例教你在 Java 8 中如何处理日期和时间?</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/06/19/SimpleDateFormat/">SimpleDateFormat 如何安全的使用？</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/05/26/paper/">苦逼的毕业论文经历</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/04/30/springboot_SpringApplication/">Spring Boot 2.0系列文章(七)：SpringApplication 深入探索</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/04/24/Distributed_lock/">分布式锁看这篇就够了</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/04/19/SpringBootApplication-annotation/">Spring Boot 2.0系列文章(六)：Spring Boot 2.0中SpringBootApplication注解详解</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/04/18/spring_boot2_project/">Spring Boot 2.0系列文章(五)：Spring Boot 2.0 项目源码结构预览</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/04/15/springboot2_code/">Spring Boot 2.0系列文章(四)：Spring Boot 2.0 源码阅读环境搭建</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/04/13/Spring_Boot_2.0_Configuration_Changelog/">Spring Boot 2.0系列文章(三)：Spring Boot 2.0 配置改变</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/03/27/blogs/">写这么多系列博客，怪不得找不到女朋友</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/03/06/SpringBoot2-new-features/">Spring Boot 2.0系列文章(二)：Spring Boot 2.0 新特性详解</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/03/06/SpringBoot2-Migration-Guide/">Spring Boot 2.0系列文章(一)：Spring Boot 2.0 迁移指南</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/03/04/springboot-vedio/">小马哥 《Java 微服务实践 - Spring Boot 系列》强烈推荐</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/03/04/springcloud-vedio/">小马哥 《Java 微服务实践 - Spring Cloud 系列》强烈推荐</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/02/28/Java-Memory-Model/">《深入理解 Java 内存模型》读书笔记</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/02/07/SpringBoot-RocketMQ/">Spring Boot系列文章（六）：SpringBoot RocketMQ 整合使用和监控</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/02/07/rocketmq-example/">RocketMQ系列文章（三）：RocketMQ 简单的消息示例</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/02/06/RocketMQ-install/">RocketMQ系列文章（二）：RocketMQ 安装及快速入门</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/02/05/RocketMQ/">RocketMQ系列文章（一）：RocketMQ 初探</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/01/28/RabbitMQ/">Spring Boot系列文章（五）：SpringBoot RabbitMQ 整合进阶版</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/01/27/SpringBoot-ActiveMQ/">Spring Boot系列文章（四）：SpringBoot ActiveMQ 整合使用</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/01/26/SpringBoot-RabbitMQ/">Spring Boot系列文章（三）：SpringBoot  RabbitMQ 整合使用</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/01/25/Docker-install/">Docker系列文章（二）：Mac 安装 Docker 及常用命令</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/01/24/mac/">MacBook Pro 初体验</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/01/17/SpringBoot-Admin/">Spring Boot系列文章（二）：SpringBoot Admin 使用指南</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/01/09/lombok/">Lombok 看这篇就够了</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/01/05/SpringBoot-Kafka/">Spring Boot系列文章（一）：SpringBoot Kafka 整合使用</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/01/04/Kafka/">Kafka 安装及快速入门</a></li><li class="post-list-item"><a class="post-list-link" href="/2018/01/04/weixin/">为什么要重新运营以前的公众号呢？</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/12/27/consul-install/">Windows 下安装 Consul</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/12/25/ELK/">Elasticsearch 系列文章（五）：ELK 实时日志分析平台环境搭建</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/12/18/hexo-yilia/">Hexo + yilia 搭建博客可能会遇到的所有疑问</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/12/13/Google-Developer-Days/">谷歌开发者大会收获满满，不去真 “可惜” 了</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/12/09/CodeMirror/">使用 CodeMirror 打造属于自己的在线代码编辑器</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/12/08/netty-01-env/">Netty系列文章（一）：Netty 源码阅读之初始环境搭建</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/12/03/RestTemplate/">RestTemplate 详解</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/12/02/wx-01/">实习圈群里提问小记</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/11/26/Docker-harbor/">Docker系列文章（一）：基于 Harbor 搭建 Docker 私有镜像仓库</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/11/18/flow-control/">基于分布式环境下限流系统的设计</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/11/18/Money-management/">谈谈我的理财</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/11/11/recommended-books/">送你一份双十一剁手书单【墙裂推荐】</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/11/11/Maven-dependencies-dependencyManagement/">Maven 中 dependencies 与 dependencyManagement 的区别</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/10/28/Data-Desensitization/">小白谈数据脱敏</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/10/21/HBase-metrics/">HBase 集群监控</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/10/18/ElasticSearch-nodes-metrics/">Elasticsearch 系列文章（四）：ElasticSearch 单个节点监控</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/10/15/ElasticSearch-cluster-health-metrics/">Elasticsearch 系列文章（三）：ElasticSearch 集群监控</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/10/14/Nexus3-Maven/">Centos7 搭建最新 Nexus3 Maven 私服</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/10/14/JsonPath/">JsonPath —— JSON 解析神器</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/09/23/Guava-limit/">Google Guava 缓存实现接口的限流</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/09/17/Interview-summary/">面试过阿里等互联网大公司，我知道了这些套路</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/09/15/linux-lua-lfs-install/">Linux 下 lua 开发环境安装及安装 luafilesystem</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/09/09/Elasticsearch-install/">Elasticsearch 系列文章（二）：全文搜索引擎 Elasticsearch 集群搭建入门教程</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/09/08/Elasticsearch-analyzers/">Elasticsearch 系列文章（一）：Elasticsearch 默认分词器和中分分词器之间的比较及使用方法</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/08/28/recommend-books/">那些年我看过的书 —— 致敬我的大学生活 —— Say Good Bye ！</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/08/18/Ubuntu-install-Nginx/">Ubuntu16.10 安装 Nginx</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/08/11/most-success/">马云热血励志演讲《最伟大的成功》</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/08/08/android-projects/">源码大招：不服来战！撸这些完整项目，你不牛逼都难！</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/08/05/Nginx/">Nginx 基本知识快速入门</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/08/04/alibaba/">秋招第三站 —— 内推阿里（一面）</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/08/04/yaxin/">秋招第一站 —— 亚信科技</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/08/04/iqiyi/">秋招第二站 —— 内推爱奇艺（一面二面）</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/07/29/ThreadPool/">Java 线程池艺术探索</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/07/25/Java-performance-tuning/">Java 性能调优需要格外注意的细节</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/07/21/Spring-MVC03/">Spring MVC系列文章（五）：看透 Spring MVC 源代码分析与实践 ——  Spring MVC 组件分析</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/07/14/Spring-MVC01/">Spring MVC系列文章（三）：看透 Spring MVC 源代码分析与实践 ——  网站基础知识</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/07/14/Spring-MVC02/">Spring MVC系列文章（四）：看透 Spring MVC 源代码分析与实践 ——  俯视 Spring MVC</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/07/09/servlet/">通过源码详解 Servlet</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/28/Velocity-foreach/">Velocity 循环指令一种好的解决方法</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/23/java-io/">Java IO流学习超详细总结（图文并茂）</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/23/AJAX/">AJAX 学习</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/20/Java-error1/">java.sql.SQLException Field 'id' doesn't have a default value</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/19/中缀表达式转换成前缀和后缀表达式这类题目的超实用解题技巧/">中缀表达式转换成前缀和后缀表达式这类题目的超实用解题技巧</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/18/Bootstrap入门需掌握的知识点（二）/">Bootstrap入门需掌握的知识点（二）</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/18/Bootstrap入门需掌握的知识点（一）/">Bootstrap入门需掌握的知识点（一）</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/18/循环队列的相关条件和公式/">循环队列的相关条件和公式</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/17/详解 Filter 过滤器/">详解 Filter 过滤器</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/17/blog-talk/">搭建一个博客项目后的碎碎念</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/17/详细深入分析 Java ClassLoader 工作机制/">详细深入分析 Java ClassLoader 工作机制</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/16/通过项目逐步深入了解Spring MVC（一）/">通过项目逐步深入了解Spring MVC（一）</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/15/通过项目逐步深入了解Mybatis(四)/">通过项目逐步深入了解Mybatis（四）</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/14/通过项目逐步深入了解Mybatis(三)/">通过项目逐步深入了解Mybatis（三）</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/Hexo-yilia-toc/">Hexo + yilia 主题实现文章目录</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/HashMap-Hashtable/">HashMap、Hashtable、HashSet 和 ConcurrentHashMap 的比较</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/Spring MVC+Hibernate JPA搭建的博客系统项目中所遇到的坑/">Spring MVC系列文章（二）：Spring MVC+Hibernate JPA搭建的博客系统项目中所遇到的坑</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/Spring MVC + Hibernate JPA + Bootstrap 搭建的博客系统/">Spring MVC系列文章（一）：Spring MVC + Hibernate JPA + Bootstrap 搭建的博客系统 Demo</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/Java-Thread/">《Java 多线程编程核心技术》学习笔记及总结</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/Python爬虫实战之爬取糗事百科段子/">Python爬虫实战之爬取糗事百科段子</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/通过项目逐步深入了解Mybatis(二)/">通过项目逐步深入了解Mybatis（二）</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/Pyspider框架 —— Python爬虫实战之爬取 V2EX 网站帖子/">Pyspider框架 —— Python爬虫实战之爬取 V2EX 网站帖子</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/MySQL-select-good/">MySQL 处理海量数据时的一些优化查询速度方法</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/MyBatis-foreach/">MyBatis的foreach语句详解</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/Java连接Oracle数据库的三种连接方式/">Java连接Oracle数据库的三种连接方式</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/【字符串】判断两字符串是否互为旋转词？/">【字符串】判断两字符串是否互为旋转词？</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/【字符串】字符串逆序/">字符串</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/feiji/">记录下自己第一次坐飞机的感受</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/JVM性能调优监控工具jps、jstack、jmap、jhat、jstat等使用详解/">JVM性能调优监控工具jps、jstack、jmap、jhat、jstat等使用详解</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/Java-16-lession/">《疯狂 Java 突破程序员基本功的 16 课》读书笔记</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/奇怪的Java题：为什么128 == 128返回为False，而127 == 127会返回为True-/">奇怪的Java题：为什么128 == 128返回为False，而127 == 127会返回为True?</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/利用Github Page 搭建个人博客网站/">利用Github Page 搭建个人博客网站</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/深入分析 Java Web 中的中文编码问题/">深入分析 Java Web 中的中文编码问题</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/程序访问文件的几种方式/">程序访问文件的几种方式</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/深度探究Java 中 finally 语句块/">深度探究Java 中 finally 语句块</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/解决jdk1.8中发送邮件失败（handshake_failure）问题/">解决jdk1.8中发送邮件失败（handshake_failure）问题</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/java-var/">从对象深入分析 Java 中实例变量和类变量的区别</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/String-new/">关于String s = new String("xyz"); 创建几个对象的问题</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/java读取文件/">Java读取文件</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/Java NIO 系列教程/">Java NIO 系列教程</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/13/Python爬虫实战之爬取百度贴吧帖子/">Python爬虫实战之爬取百度贴吧帖子</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/12/通过项目逐步深入了解Mybatis(一)/">通过项目逐步深入了解Mybatis（一）</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/06/02/poetry2/"> 六月 —— 愿你做最美好的自己！</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/05/12/poetry/">最近很火的鸡汤，分享给大家</a></li><li class="post-list-item"><a class="post-list-link" href="/2017/04/13/Hexo-yilia-changyan/">Github pages + Hexo 博客 yilia 主题使用畅言评论系统</a></li></ul>
    <script src="https://7.url.cn/edu/jslib/comb/require-2.1.6,jquery-1.9.1.min.js"></script>
    <script>
        $(".post-list").addClass("toc-article");
        $(".post-list-item a").attr("target","_blank");
        $("#post-nav-button > a:nth-child(2)").click(function() {
            $(".fa-bars, .fa-times").toggle();
            $(".post-list").toggle(300);
            if ($(".toc").length > 0) {
                $("#toc, #tocButton").toggle(200, function() {
                    if ($(".switch-area").is(":visible")) {
                        $("#tocButton").attr("value", valueHide);
                        }
                    })
            }
            else {
            }
        })
    </script>



    <script>
        
    </script>
</div>
      <footer id="footer">
    <div class="outer">
        <div id="footer-info">
            <div class="footer-left">
                &copy; 2019 zhisheng
            </div>
        </div>
        
            <div class="visit">
                
                    <span id="busuanzi_container_site_pv" style='display:none'>
                        <span id="site-visit" >本站总访问量: 
                            <span id="busuanzi_value_site_pv"></span>
                        </span>
                    </span>
                
                
                    <span>, </span>
                
                
                    <span id="busuanzi_container_page_pv" style='display:none'>
                        <span id="page-visit">本文总阅读量: 
                            <span id="busuanzi_value_page_pv"></span>
                        </span>
                    </span>
                
            </div>
        
    </div>
</footer>

    </div>
    <script src="https://7.url.cn/edu/jslib/comb/require-2.1.6,jquery-1.9.1.min.js"></script>
<script src="/js/main.js"></script>

    <script>
        $(document).ready(function() {
            var backgroundnum = 24;
            var backgroundimg = "url(/background/bg-x.jpg)".replace(/x/gi, Math.ceil(Math.random() * backgroundnum));
            $("#mobile-nav").css({"background-image": backgroundimg,"background-size": "cover","background-position": "center"});
            $(".left-col").css({"background-image": backgroundimg,"background-size": "cover","background-position": "center"});
        })
    </script>




	<script>
	var _hmt = _hmt || [];
	(function() {
	  var hm = document.createElement("script");
	  hm.src = "https://hm.baidu.com/hm.js?c41be5a0c9f014e977695f66c065b5d3";
	  var s = document.getElementsByTagName("script")[0]; 
	  s.parentNode.insertBefore(hm, s);
	})();
	</script>


<div class="scroll" id="scroll">
    <a href="#"><i class="fa fa-arrow-up"></i></a>
    <a href="#comments"><i class="fa fa-comments-o"></i></a>
    <a href="#footer"><i class="fa fa-arrow-down"></i></a>
</div>
<script>
    $(document).ready(function() {
        if ($("#comments").length < 1) {
            $("#scroll > a:nth-child(2)").hide();
        };
    })
</script>

<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js">
</script>

  <script language="javascript">
    $(function() {
        $("a[title]").each(function() {
            var a = $(this);
            var title = a.attr('title');
            if (title == undefined || title == "") return;
            a.data('title', title).removeAttr('title').hover(

            function() {
                var offset = a.offset();
                $("<div id=\"anchortitlecontainer\"></div>").appendTo($("body")).html(title).css({
                    top: offset.top - a.outerHeight() - 15,
                    left: offset.left + a.outerWidth()/2 + 1
                }).fadeIn(function() {
                    var pop = $(this);
                    setTimeout(function() {
                        pop.remove();
                    }, pop.text().length * 800);
                });
            }, function() {
                $("#anchortitlecontainer").remove();
            });
        });
    });
</script>


  </div>
</body>
</html>